zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    39     return 0;
    40 }
    View Code

    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
    ", op);
    83     for (auto i : ans) printf("%d ", i);
    84     puts("");
    85     return 0;
    86 }
    View Code

    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
    ", ans);
    71     return 0;
    72 }
    View Code

    D:

    比赛打到这里,整个人开始自闭起来。读完题就意识到trie只是个幌子,正解是dp,但完全不会做,赛后看大佬代码才懂。

    n<=1000已经强烈暗示这很可能是O(n^2)的算法了。

     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
    ", dp[0][0][1]);
    65     return 0;
    66 }
    View Code

    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 }
    View Code

    F1 && F2:

    看完题就觉得zen zen不可做,溜了溜了。这数据量我很怀疑是不是状压dp。(被官方题解爆智商了。

  • 相关阅读:
    celery beat之pidfile already exists问题
    HBase源码系列之HFile
    吴裕雄--天生自然 JAVA开发学习:集合框架
    吴裕雄--天生自然 诗经:小池
    吴裕雄--天生自然 诗经:所见
    吴裕雄--天生自然 JAVA开发学习:数据结构
    吴裕雄--天生自然 JAVA开发学习:包(package)
    吴裕雄--天生自然 JAVA开发学习:接口
    吴裕雄--天生自然 JAVA开发学习:封装
    吴裕雄--天生自然 JAVA开发学习:抽象类
  • 原文地址:https://www.cnblogs.com/JHSeng/p/10768886.html
Copyright © 2011-2022 走看看