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。

原文地址:https://www.cnblogs.com/JHSeng/p/10768886.html

时间: 2024-10-09 04:13:30

Codeforces Round #554(div. 2)的相关文章

Codeforces Round #554 (Div. 2) C.Neko does Maths (gcd的运用)

题目链接:https://codeforces.com/contest/1152/problem/C 题目大意:给定两个正整数a,b,其中(1<=a,b<=1e9),求一个正整数k(0<=k),使得a+k与b+k的最小公倍数最小. 解题思路:首先我们需要知道gcd(a,b)=gcd(a,b-a)=gcd(b,b-a)(b>a)的 我们要求的是lcm(a+k,b+k)=(a+k)(b+k)/gcd(a+k,b+k)=(a+k)(b+k)/gcd(a+k,b-a) 因为b-a是定值,所

Codeforces Round #554 (Div. 2) 1152C. Neko does Maths

学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152C. Neko does Maths 题目链接:"https://codeforces.com/contest/1152/problem/C" 题目大意:给你两个数a,b,现在要你找出一个数k使得(a+k)和(b+k)的最小公倍数最小. 题目思路:暴力(逃) 这题没得思路,想了想既然求LCM了那么和GCD说不定有点关系 然后就没有然后了 比赛的时候交了一发暴力上去,然并软 赛后补题,题解里面

Codeforces Round #554 (Div. 2) C. Neko does Maths (数论 GCD(a,b) = GCD(a,b-a))

传送门 •题意 给出两个正整数 a,b: 求解 k ,使得 LCM(a+k,b+k) 最小,如果有多个 k 使得 LCM() 最小,输出最小的k: •思路 时隔很久,又重新做这个题 温故果然可以知新? 重要知识点 GCD(a,b)=GCD(a,b-a)=GCD(b,b-a) (b>a) 证明: 设GCD(a,b)=c 则a%c=0,b%c=0,(b-a)%c=0 所以GCD(a,b-a)=c 得GCD(a,b)=GCD(a,b-a) gcd(a+k,b-a)肯定是(b-a)的因子 所以gcd(a

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f