Codeforces Round #554(div. 2)
Posted jhseng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #554(div. 2)相关的知识,希望对你有一定的参考价值。
距离上次打cf已经不知道过了多久,看到最近的contest都很水,于是想上上分,然后就3题滚了……(顺便吐槽cf好卡
题目链接:http://codeforces.com/contest/1152
A:
一眼题,奇+偶才能等于奇
1 #include <bits/stdc++.h> 2 /* define */ 3 #define ll long long 4 #define dou double 5 #define pb emplace_back 6 #define mp make_pair 7 #define fir first 8 #define sec second 9 #define sot(a,b) sort(a+1,a+1+b) 10 #define rep1(i,a,b) for(int i=a;i<=b;++i) 11 #define rep0(i,a,b) for(int i=a;i<b;++i) 12 #define repa(i,a) for(auto &i:a) 13 #define eps 1e-8 14 #define int_inf 0x3f3f3f3f 15 #define ll_inf 0x7f7f7f7f7f7f7f7f 16 #define lson curPos<<1 17 #define rson (curPos<<1)+1 18 /* namespace */ 19 using namespace std; 20 /* header end */ 21 22 const int maxn=1e5; 23 int n,m,ja=0,oa=0,jb=0,ob=0; 24 25 int main() 26 { 27 scanf("%d%d",&n,&m); 28 rep1(i,1,n) { 29 int x; scanf("%d",&x); 30 if (x&1) ja++; else oa++; 31 } 32 rep1(i,1,m) { 33 int x; scanf("%d",&x); 34 if (x&1) jb++; else ob++; 35 } 36 int ans=0; 37 ans=min(ja,ob); ans+=min(oa,jb); 38 printf("%d\n",ans); 39 return 0; 40 }
B:
给定整数x,轮流执行两种操作:1)x=x xor 2^n-1,2)x++。问要经过几次操作才能把x变为2^n-1的形式。看到这个题第一反应居然是……不会,发了好久的呆才缓过来。
对于当前的x,转化为二进制,并找到最高位的0。比如10011,最高位0到最右边长度为4,那就用1111去xor x。
事实上写起来也不用这么麻烦,一直用跟x等长的"1"串去xor x,直到(++x)-lowbit(x)==0就可以了。
在?为什么没有一眼秒?
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 vector<int>ans; 42 int n, op = 0; 43 44 inline int lowbit(int x) 45 { 46 return x & -x; 47 } 48 49 int get(int x) 50 { 51 int ret = 1; 52 while (ret <= x) ret <<= 1; 53 return ret - 1; 54 } 55 56 int calc(int x) 57 { 58 int ret = 0, tmp = 1; 59 while (tmp <= x) ret++, tmp <<= 1; 60 return ret; 61 } 62 63 int check(int x) 64 { 65 x++; 66 if (x - lowbit(x)) return true; else return false; 67 } 68 69 int main() 70 { 71 scanf("%d", &n); 72 while (check(n)) 73 { 74 op++; 75 if (op & 1) 76 { 77 ans.pb(calc(n)); 78 n ^= get(n); 79 } 80 else n++; 81 } 82 printf("%d\n", op); 83 for (auto i : ans) printf("%d ", i); 84 puts(""); 85 return 0; 86 }
C:
给定整数a,b,求一非负数k,使得lcm(a+k,b+k)最小。
gcd(a+k,b+k)==gcd(a+k,abs(a-b)),它还有个名字叫更相减损术(想起来了吧)。令delta=abs(a-b),枚举delta的所有因子并反推k。
为什么要这样做?题目让lcm最小,那么就是要求最大的gcd,最大的gcd必定是两数中最大的约数,由于题目中delta是定值,所以就可以枚举delta的约数,然后把a凑到含有此约数为止,需要凑的值k=x-a%x (x | delta)。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 ll a, b, minLcm = 0, ans = 0, delta; 42 43 ll lcm(ll a, ll b) 44 { 45 return a / __gcd(a, b) * b; 46 } 47 48 int main() 49 { 50 scanf("%lld%lld", &a, &b); delta = abs(b - a); 51 minLcm = lcm(a, b); 52 for (ll i = 1; i * i <= delta; i++) 53 { 54 if (!(delta % i)) 55 { 56 ll tmp = i - (a % i); 57 if (lcm(a + tmp, b + tmp) < minLcm) 58 { 59 minLcm = lcm(a + tmp, b + tmp); 60 ans = tmp; 61 } 62 tmp = (delta / i) - (a % (delta / i)); 63 if (lcm(a + tmp, b + tmp) < minLcm) 64 { 65 minLcm = lcm(a + tmp, b + tmp); 66 ans = tmp; 67 } 68 } 69 } 70 printf("%lld\n", ans); 71 return 0; 72 }
D:
比赛打到这里,整个人开始自闭起来。读完题就意识到trie只是个幌子,正解是dp,但完全不会做,赛后看大佬代码才懂。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 const int maxn = 1e3 + 10; 42 const int mod = 1e9 + 7; 43 44 int n, dp[maxn][maxn][2]; 45 46 int main() 47 { 48 scanf("%d", &n); 49 rep1(i, 0, n) 50 { 51 dp[i][i + 1][0] = -int_inf; 52 dp[n + 1][i][0] = -int_inf; 53 } 54 dp[n][n][0] = dp[n][n][1] = 0; 55 for (int i = n; i >= 0; i--) 56 { 57 for (int j = i - (j == n); j >= 0; j--) 58 { 59 dp[i][j][0] = (dp[i][j + 1][1] + dp[i + 1][j][1]) % mod; 60 dp[i][j][1] = (dp[i][j + 1][0] + dp[i + 1][j][1] + 1) % mod; 61 dp[i][j][1] = (dp[i][j][0] + ((i + j) & 1)) % mod; 62 } 63 } 64 printf("%d\n", dp[0][0][1]); 65 return 0; 66 }
E:
看完题就意识到这肯定是搜索相关,图论题。题意那么绕,其实只是输出欧拉路而已。(居然是模板题,出题人莫不是宫崎英高?(本来可以四题的,被D卡到自闭不想动,摔
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 const int maxn = 1e5 + 10; 42 int n, a[maxn], b[maxn]; 43 map<int, multiset<int>>graph; 44 vector<int>eulerPath, oddPoint; 45 46 void getEulerPath(int u) 47 { 48 while (graph[u].size()) 49 { 50 int v = *graph[u].begin(); 51 graph[u].erase(graph[u].begin()); 52 graph[v].erase(graph[v].find(u)); 53 getEulerPath(v); 54 } 55 eulerPath.pb(u); 56 } 57 58 bool checkEuler() 59 { 60 for (auto i : graph) 61 { 62 if ((int)i.second.size() & 1) oddPoint.pb(i.first); 63 } 64 return ((!(int)oddPoint.size()) || ((int)oddPoint.size() == 2)); 65 } 66 67 int main() 68 { 69 scanf("%d", &n); 70 rep0(i, 1, n) scanf("%d", &a[i]); 71 rep0(i, 1, n) scanf("%d", &b[i]); 72 rep0(i, 1, n) 73 { 74 if (a[i] > b[i]) return puts("-1"), 0; 75 graph[a[i]].insert(b[i]); 76 graph[b[i]].insert(a[i]); 77 } 78 if (!checkEuler()) return puts("-1"), 0; 79 getEulerPath(oddPoint.empty() ? graph.begin()->first : oddPoint[0]); 80 if ((int)eulerPath.size() != n) return puts("-1"), 0; 81 for (auto i : eulerPath) printf("%d ", i); 82 puts(""); 83 return 0; 84 }
F1 && F2:
看完题就觉得zen zen不可做,溜了溜了。这数据量我很怀疑是不是状压dp。
以上是关于Codeforces Round #554(div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #554 (Div. 2) C.Neko does Maths (gcd的运用)
Codeforces Round #554 (Div. 2) C. Neko does Maths (数论 GCD(a,b) = GCD(a,b-a))
Codeforces Round #705 (Div. 2)
Codeforces Round #774 (Div. 2)