Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! A、Johnny and Ancient Computer B、Johnny and His Hobbies C、Johnny and Another Rating Drop

题目链接:A、Johnny and Ancient Computer

 

题意:

给你两个数a,b。问你可不可以通过左移位运算或者右移位运算使得它们两个相等。可以的话输出操作次数,不可以输出-1

一次操作可以最多左移3次或者右移3次

 

题解:

首先找寻一下这两个数的二进制形式下最右边那个1在什么位置。然后看一下它们的差距是多少(设为x)

那么就让a,b中小的那个数左移x位。之后判断一下它们两个相等不相等就可以了

 

代码:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string>
 5 #include<queue>
 6 #include<deque>
 7 #include<string.h>
 8 #include<map>
 9 #include <iostream>
10 #include <math.h>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=500+10;
14 int main()
15 {
16     ll t;
17     scanf("%I64d",&t);
18     while(t--)
19     {
20         ll a,b,sum1=0,sum2=0,sum=0;
21         scanf("%I64d%I64d",&a,&b);
22         ll aa=a,bb=b;//printf("%I64d**%I64d\n",aa,aa&1);
23         while((aa&1)==0)
24         {
25 
26             sum1++;
27             aa>>=1;
28         }
29         while((bb&1)==0)
30         {
31             sum2++;
32             bb>>=1;
33         }
34         if(a<b) swap(a,b);
35         //printf("%I64d****%I64d %I64d\n",sum1-sum2,sum1,sum2);
36         if(sum1<sum2) swap(sum1,sum2);
37 
38         if((sum1-sum2)==0)
39         {
40             if(a==b)
41             printf("0\n");
42             else printf("-1\n");
43         }
44         else if((sum1-sum2)%3)
45         {
46 
47             sum=(sum1-sum2)/3+1;
48             //printf("%I64d %I64d %I64d\n",sum1-sum2,b,b<<(sum1-sum2));
49             b<<=(sum1-sum2);
50 
51             if(a==b)
52             printf("%I64d\n",sum);
53             else printf("-1\n");
54         }
55         else
56         {
57             sum=(sum1-sum2)/3;
58             b<<=(sum1-sum2);
59             if(a==b)
60             printf("%I64d\n",sum);
61             else printf("-1\n");
62         }
63     }
64     return 0;
65 }
View Code

 

 

题目链接:B、Johnny and His Hobbies

 

题意:

给你一个有n个元素的集合v,给你两个集合a,b(集合内元素都是int类型)。如果把a数组中元素和b中元素都分别按照从小到大排序。如果排序后两个集合一摸一样,那就说着a,b两个集合相等

现在你需要找到一个最小的k,使得v集合中每一个元素都与k进行异或操作,你需要保证异或后得到的那个集合和原集合相等。

如果你找不到这个k,那就输出-1

 

题解:

首先如果n为奇数那么肯定输出-1,因为如果要满足题意的话,那肯定是v[i]异或k之后这个值v[i]相互对应,毕竟k被异或两个相当于没有被异或,即v[i]=v[i]^k^k

之后我还想着n为偶数情况也是找规律,没想到。。。

 

偶数方面就暴力,因为n本身就不大

如果v集合中两个元素x和y相对应,那么x^y这个值就满足题意(虽然可能不是最小的k),那么我们就先确定x为v集合中第一个元素v[1],对y就是暴力枚举。

找到x和y之后,我们这里设ans=x^y

那么v集合中其他元素与ans异或之后的元素肯定也在v集合中,如果有一个不在,那么ans就不满足题意

 

用一个变量 minn来保存那个满足题意得最小的ans就行

 

代码:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string>
 5 #include<queue>
 6 #include<deque>
 7 #include<string.h>
 8 #include<map>
 9 #include <iostream>
10 #include <math.h>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=1024+10;
14 const int INF=0x3f3f3f3f;
15 int w[maxn],v[maxn];
16 int main()
17 {
18     int t;
19     scanf("%d",&t);
20     while(t--)
21     {
22         int n;
23         memset(w,0,sizeof(w));
24         scanf("%d",&n);
25         for(int i=1;i<=n;++i)
26         {
27             scanf("%d",&v[i]);
28             w[v[i]]=1;
29         }
30         if(n%2)
31         {
32             printf("-1\n");
33             continue;
34         }
35         //sort(v+1,v+1+n);
36         int minn=INF;
37         for(int i=2;i<=n;++i)
38         {
39             int ans=v[1]^v[i],flag=0;
40             for(int j=2;j<=n;++j)
41             {
42                 if(i==j) continue;
43                 if(w[ans^v[j]]);
44                 else
45                 {
46                     flag=1;
47                     break;
48                 }
49             }
50             if(flag==0)
51             {
52                 minn=min(minn,ans);
53             }
54         }
55         if(minn==INF)
56         {
57             printf("-1\n");
58         }
59         else
60         {
61             printf("%d\n",minn);
62         }
63     }
64     return 0;
65 }
View Code

 

 

题目链接:C、Johnny and Another Rating Drop

 

题意:

给你一个n,然后找出来1,2,3...n中相邻得两个数中二进制形式下有多少位不相同

例如3和4

3二进制为011

4二进制为100

那么它们两个有3位不同

 

题解:

找规律,好多题解都说的找规律;没找规律的题解也没看太明白

F(n)=F(n/2)+n

 

代码:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string>
 5 #include<queue>
 6 #include<deque>
 7 #include<string.h>
 8 #include<map>
 9 #include <iostream>
10 #include <math.h>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=1024+10;
14 const int INF=0x3f3f3f3f;
15 int main()
16 {
17     int t;
18     cin>>t;
19     while(t--)
20     {
21         long long n,ans=0;
22         cin>>n;
23         while(n)
24         {
25             ans+=n;
26             n/=2;
27         }
28         cout<<ans<<endl;
29     }
30 }

 

posted @ 2020-07-16 16:16  kongbursi  阅读(108)  评论(0编辑  收藏  举报