Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! (A-C) (持续补题跟进)

Posted fantadevourer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! (A-C) (持续补题跟进)相关的知识,希望对你有一定的参考价值。

已给出A,B题解,C的代码正确性暂未证明。D,E,F待补。(持续补题...)

------------------------------------------------------------------------------------------------------------------

A. Johnny and Ancient Computer

技术图片

 

 

技术图片

 

 

题意:给你两个数a和b,要求将a通过数次合法操作转换为b,输出最小的操作数,若无法转换为b,则输出-1。合法操作有:乘2、4、8,除以2、4、8。(除以操作只在能被整除的情况下执行)

思路:转换是双向的,所以我们认为问题是怎么由较大数转换为较小数。认为a是较大值,b是较小值,我们可以将问题转化为处理a / b的值。

bt1?t2?tn?=a

t1?t2?tn?=a/b?

  所以,如果特判a % b != 0必定无法转换,输出-1。然后令k =  a / b,用k去试探是否可以被2,4,8整除。由于需要输出最小操作数,所以能被较大数整除就除以较大数。遇到两种情况退出循环:

    1、 k == 1,这时说明已经完成了操作,输出操作数即可。

    2、 k != 1 && k % 2 == 1,这说明无法操作,输出-1。

代码:

 

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1, M = 1;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 typedef pair<int, int> PII;
 7 #define rep(i, x, y) for(i=x;i<=y;i++)
 8 #define ref(i, x, y) for(i=x;i>=y;i--)
 9 #define MEM(a, x) memset(a, x, sizeof(a))
10 #define Sca(x) scanf("%d", &x)
11 #define Scl(x) scanf("%lld", &x)
12 #define Scf(x) scanf("%f", &x)
13 #define Sclf(x) scanf("%lf", &x)
14 #define pb push_back
15 #define mp make_pair
16 #define fi first
17 #define se second
18 #define lb lower_bound
19 #define ub upper_bound
20 #define endl ‘
‘
21 
22 int T, n;
23 bool vis[N];
24 
25 int main()
26 {
27     ios::sync_with_stdio(false);
28     ull a, b;
29     cin >> T;
30     while (T--) {
31         cin >> a >> b;
32         if (a < b) swap(a, b);
33         if (a % b) {
34             cout << - 1 << endl;
35             continue;
36         }
37         ll k = a / b;
38         ll cnt = 0;
39         while (k) {
40             if (k % 8 == 0) {
41                 k /= 8;
42                 cnt++;
43             }else if (k % 4 == 0) {
44                 k /= 4;
45                 cnt++;
46             }else if (k % 2 == 0) {
47                 k /= 2;
48                 cnt++;
49             }else if (k == 1) {
50                 break;
51             }else {
52                 cnt = -1;
53                 break;
54             }
55         }
56         cout << cnt << endl;
57     }
58     return 0;
59 }
View Code

总结:比赛时写了ios::sync_with_stdio(false);但是还是用了puts导致wa了两次,拖了些时间。下次注意不能再犯傻了。

 B. Johnny and His Hobbies

技术图片 

技术图片

 

 

题意:给出一个集合,要求找到一个值k,使得集合中每一个值ai 变为 ai ^ k,仍使新集合等于原集合。

思路:因为所有n的总和不超过1024,所以我们可以从a[1] ^ a[2...n]枚举k的所有值。确定k值后在[2, n]里对每一个a[i]确定它对应的a[i] ^ k, 二分查找是否存在这个值。答案取最小值。时间复杂度大概是O(n2logn)。(应该没算错吧)

代码:

 

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2048, M = 1;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 typedef pair<int, int> PII;
 7 #define rep(i, x, y) for(i=x;i<=y;i++)
 8 #define ref(i, x, y) for(i=x;i>=y;i--)
 9 #define MEM(a, x) memset(a, x, sizeof(a))
10 #define Sca(x) scanf("%d", &x)
11 #define Scl(x) scanf("%lld", &x)
12 #define Scf(x) scanf("%f", &x)
13 #define Sclf(x) scanf("%lf", &x)
14 #define pb push_back
15 #define mp make_pair
16 #define fi first
17 #define se second
18 #define lb lower_bound
19 #define ub upper_bound
20 #define endl ‘
‘
21 
22 int T, n;
23 ll a[N];
24 bool vis[N];
25 
26 int bsearch(int l, int r, ll x)
27 {
28     while (l < r) {
29         int mid = l + r >> 1;
30         if (a[mid] >= x) r = mid;
31         else l = mid + 1;
32     }
33     return l;
34 }
35 
36 int main()
37 {
38     ios::sync_with_stdio(false);
39     cin >> T;
40     while (T--) {
41         cin >> n;
42         for (int i = 1; i <= n; i++) 
43             cin >> a[i];
44         if (n % 2) {
45             cout << -1 << endl;
46             continue;
47         }
48         int cnt = 0;
49         ll res = 0x3f3f3f3f;
50         sort(a+1, a+1+n);
51         for (int i = 2; i <= n; i++) {
52             ll ans = a[1] ^ a[i];
53             cnt = 2;
54             for (int j = 2; j <= n; j++) {
55                 if (j == i) continue;
56                 ll aim = ans ^ a[j];
57                 int pos = bsearch(1, n, aim);
58                 // cout << "j = " << j << "  pos = " << pos << endl;
59                 if (a[pos] == aim) {
60                     cnt ++;
61                 }else {
62                     break;
63                 }
64             }
65             if (cnt == n) {
66                 res = min(res, ans);
67             }
68         }
69         if (res == 0x3f3f3f3f) res = -1;
70         cout << res << endl;
71     }
72     return 0;
73 }
View Code

 

 

 

总结:拿到题目时就想过枚举k了,不过没敢写,硬是找规律找了好久。。。

 

C. Johnny and Another Rating Drop

技术图片

 

 

技术图片

 

 

题意:定义了一个不公平值,意味两个数的二进制表示中有多少位不相同。给出一个n,求出0, 1, ... , n中每两个连续的数的不公平值的和。

 

思路:比赛时我写了前几个值的和,找规律发现答案是2 * n - t,其中t为n和0的不公平值。证明和正解之后慢慢补。

 

代码:

 

 

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1, M = 1;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 typedef pair<int, int> PII;
 7 #define rep(i, x, y) for(i=x;i<=y;i++)
 8 #define ref(i, x, y) for(i=x;i>=y;i--)
 9 #define MEM(a, x) memset(a, x, sizeof(a))
10 #define Sca(x) scanf("%d", &x)
11 #define Scl(x) scanf("%lld", &x)
12 #define Scf(x) scanf("%f", &x)
13 #define Sclf(x) scanf("%lf", &x)
14 #define pb push_back
15 #define mp make_pair
16 #define fi first
17 #define se second
18 #define lb lower_bound
19 #define ub upper_bound
20 #define endl ‘
‘
21 
22 ull T, n;
23 bool vis[N];
24 
25 int main()
26 {
27     ios::sync_with_stdio(false);
28     cin >> T;
29     while (T--) {
30         cin >> n;
31         ll temp = n;
32         ll cnt = 0;
33         while (temp) {
34             if (temp & 1) cnt++;
35             temp >>= 1;
36         }
37         cout << 2ll * n - cnt << endl;
38     }
39     return 0;
40 }
还没有证明的代码

 

 

 

 

 

 

 

 

以上是关于Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! (A-C) (持续补题跟进)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #647 (Div. 2) - Thanks, Algo Muse!

Codeforces Round #647 (Div. 2) - Thanks, Algo Muse!

Codeforces Round #647 (Div. 2) - Thanks, Algo Muse!

Codeforces Round #647 (Div. 2) B. Johnny and His Hobbies(枚举)

Codeforces Round #647 (Div. 2) B. Johnny and His Hobbies(枚举)

Codeforces Round #647 (Div. 2) D. Johnny and Contribution(BFS)