zoukankan      html  css  js  c++  java
  • Codeforces Round #552 (Div. 3)

    本场题目不难,暴力模拟大法好。A~E:模拟+暴力(有些是贪心);F:留坑待填;G:埃氏筛+贪心。

    A、Restoring Three Numbers

    思路:简单数学。

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 1e5+5;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 
    30 LL x[5], a, b, c;
    31 
    32 int main() {
    33     while(cin >> x[1] >> x[2] >> x[3] >> x[4]) {
    34         sort(x + 1, x + 5);
    35         b = (x[1] - x[2] + x[3]) / 2;
    36         c = x[3] - b;
    37         a = x[4] - b - c;
    38         cout << a << ' ' << b << ' '  << c << endl;
    39     }
    40     return 0;
    41 }
    View Code

    B、Make Them Equal

    思路:暴力+模拟。只需枚举最终的数组变成的数字(1~100)即可。

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 105;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 
    30 int n, ans, now, cha, a[maxn];
    31 bool flag;
    32 
    33 int main() {
    34     while(~scanf("%d", &n)) {
    35         for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
    36         sort(a, a + n);
    37         ans = inf;
    38         for(int j = 0; j <= 100; ++j) { // 枚举最终数组中所有的元素变为j
    39             now = 0, cha = 0; // 注意:cha的初始值为0,因为1~n每个数都可能与j相同
    40             for(int k = 0; k < n; ++k) // 找到第一个与j不同的数求差的绝对值cha
    41                 if(a[k] != j) {cha = abs(a[k] - j); break;}
    42             for(int k = 0; k < n; ++k) { // 模拟即可
    43                 if(a[k] < j) {
    44                     if(a[k] + cha == j) ++now;
    45                     else break;
    46                 }
    47                 else if(a[k] > j) {
    48                     if(a[k] - cha == j) ++now;
    49                     else break;
    50                 }
    51                 else if(a[k] == j) ++now;
    52             }
    53             if(now == n) ans = min(ans, cha);
    54         }
    55         if(ans == inf) puts("-1");
    56         else printf("%d
    ", ans);
    57     }
    58     return 0;
    59 }
    View Code

    C、Gourmet Cat

    思路:数学+暴力。由题易得一周内猫吃肉的种类依次为 a、b、c、a、c、b、a。若 $ a geq 3 land b geq 2 land c geq 2 $,则先算出轮数;(否则)剩下的枚举每一天作为起点,简单暴力模拟即可。

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 105;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 int a, b, c, d, ans, now1, now2, k, dir0[7] = {0, 1, 2, 0, 2, 1, 0}, cnt[3], cnt1[3];
    30 
    31 int main() {
    32     while(cin >> a>> b >> c) {
    33         ans = 0;
    34         memset(cnt, 0, sizeof(cnt));
    35         if(a >= 3 && b >= 2 && c >= 2) {
    36             k = min(a / 3, min(b / 2, c / 2));
    37             a -= 3 * k, b -= 2 * k, c -= 2 * k;
    38             ans = 7 * k;
    39         }
    40         cnt[0] = a, cnt[1] = b, cnt[2] = c, now2 = 0;
    41         for(int i = 0; i < 7; ++i) { // 枚举每一天作为起点
    42             cnt1[0] = cnt[0], cnt1[1] = cnt[1], cnt1[2] = cnt[2], now1 = 0;
    43             for(int j = i; ; ++j) { // 模拟
    44                 if(cnt1[dir0[j % 7]] > 0) --cnt1[dir0[j % 7]], ++now1;
    45                 else break;
    46             }
    47             now2 = max(now1, now2);
    48         }
    49         cout << ans + now2 << endl;
    50     }
    51     return 0;
    52 }
    View Code

    D、Walking Robot

    思路:简单贪心+模拟。详细思路见代码注释。

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 2e5+5;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 int n, b, a, x, y, ans, s[maxn];
    30 
    31 int main() {
    32     while(cin >> n >> x >> y) {
    33         ans = 0; b = x, a = y;
    34         for(int i = 0; i < n; ++i) cin >> s[i];
    35         for(int i = 0; i < n; ++i) {
    36             if(s[i]) { // 若被光照
    37                 if(b) { // 先考虑1个b转换成1个a
    38                     if(a + 1 <= y) --b, ++a, ++ans; // 最大不超过y
    39                     else if(a) --a, ++ans; // 不能转,则先减去a
    40                     else if(b) --b, ++ans; // a为0不能继续减,才看b是否剩余
    41                     else break;
    42                 }
    43                 else if(a) --a, ++ans; // 没有b,则只能减去a
    44                 else break; // 没法减则退出
    45             }else { // 没有被光照,不能转
    46                 if(a) --a, ++ans; // 先考虑a
    47                 else if(b) --b, ++ans; // a不能减,再考虑b,因为b的作用遇到光时能产生一个a
    48                 else break; // 没法减则退出
    49             }
    50         }
    51         cout << ans << endl;
    52     }
    53     return 0;
    54 }
    View Code

    E、Two Teams

    思路:题意很简单:每次找当前队列中技能最大的学生,向左向右分别连续选择k个学生作为自己的队员。①暴力险过。②换种思路:用大根堆维护当前序列的最大值,同时标记每个元素分别向前、向后走的第一个位置,剩下的暴力模拟即可。

    AC代码一:暴力解。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 2e5+5;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 int n, k, a, ans[maxn], siz, now, cnt, pos, mp[maxn], lt, rt;
    30 vector<int> vec;
    31 set<int> stl;
    32 set<int>::iterator it;
    33 
    34 int main() {
    35     while(~scanf("%d%d", &n, &k)) {
    36         memset(ans, 0, sizeof(ans));
    37         memset(mp, 0, sizeof(mp));
    38         vec.clear();
    39         stl.clear();
    40         cnt = 0;
    41         for(int i = 0; i < n; ++i) {
    42             scanf("%d", &a);
    43             vec.push_back(a);
    44             mp[a] = i;
    45             stl.insert(a);
    46         }
    47         while((siz = stl.size()) != 0) {
    48             it = stl.end();
    49             --it;
    50             ++cnt;
    51             if(cnt & 1) now = 1;
    52             else now = 2;
    53             pos = find(vec.begin(), vec.end(), *it) - vec.begin();
    54             lt = max(0, pos - k), rt = min(siz - 1, pos + k);
    55             for(int i = lt; i <= rt; ++i) {
    56                 ans[mp[vec[i]]] = now;
    57                 stl.erase(vec[i]);
    58             }
    59             vec.erase(vec.begin() + lt, vec.begin() + rt + 1);
    60         }
    61         for(int i = 0; i < n; ++i) printf("%d", ans[i]);
    62         puts("");
    63     }
    64     return 0;
    65 }
    View Code

    AC代码二:优化解。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const int maxn = 2e5+5;
    27 const int inf = 0x3f3f3f3f;
    28 
    29 int n, k, a, now1, now2, flag, p1, p2, num, ans[maxn], nex[maxn], per[maxn];
    30 
    31 priority_queue<pair<int, int> > que;
    32 bool vis[maxn];
    33 
    34 
    35 int main() {
    36     while(~scanf("%d%d", &n, &k)) {
    37         while(!que.empty()) que.pop();
    38         memset(ans, 0, sizeof(ans));
    39         memset(per, 0, sizeof(per));
    40         memset(nex, 0, sizeof(nex));
    41         flag = 1;
    42         memset(vis, false, sizeof(vis));
    43         for(int i = 1; i <= n; ++i) {
    44             scanf("%d", &a);
    45             que.push(make_pair(a, i));
    46             per[i] = i - 1;
    47             nex[i] = i + 1;
    48         }
    49         while(!que.empty()) {
    50             now1 = que.top().first, now2 = que.top().second, que.pop();
    51             if(vis[now2]) continue;
    52             vis[now2] = true;
    53             flag = !flag;
    54             p1 = per[now2], p2 = nex[now2], ans[now2] = flag + 1;
    55             num = k;
    56             while(num > 0 && p1 > 0) vis[p1] = true, ans[p1] = flag + 1, --num, p1 = per[p1];
    57             num = k;
    58             while(num > 0 && p2 <= n) vis[p2] = true, ans[p2] = flag + 1, --num, p2 = nex[p2];
    59             per[p2] = p1, nex[p1] = p2;
    60         }
    61         for(int i = 1; i <= n; ++i) printf("%d", ans[i]);
    62         puts("");
    63     }
    64     return 0;
    65 }
    View Code

    G、Minimum Possible LCM

    思路:埃氏筛+贪心。题意就是找出2个数使其最小公倍数最小。题目虽然给的时限是4s,但我们要换种优雅的方式来暴力,即来枚举每一个gcd(求lcm需要先求出2个数的gcd)。借用埃氏筛思想,公约数为gcd的步长增长,不难想到,头2次出现的这2个数的最小公倍数一定为gcd时的最小lcm,那么我们就可以用 $O(nlog^n)$的时间复杂度,大约是 $1.6 imes 10^8 $(1s的极限是$ 1.0 imes 10^8 $)即用1s多就可以过掉此题!

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 #include <bitset>
    18 using namespace std;
    19 typedef long long LL;
    20 typedef unsigned long long ULL;
    21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
    22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
    23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    24 const double eps = 1e-6;
    25 const double PI = acos(-1.0);
    26 const LL maxn = 1e7+5;
    27 const LL inf = 1LL << 62;
    28 
    29 
    30 int n, num, p1, p2, per1, per2, siz;
    31 LL ans, now0, now1, now2, a;
    32 
    33 bool vis[maxn];
    34 
    35 vector<int> vec[maxn];
    36 
    37 
    38 int main() {
    39     while(~scanf("%d", &n)) {
    40         ans = inf;
    41         per1 = per2 = 0;
    42         for(LL i = 0LL; i < maxn; ++i) vec[i].clear();
    43         memset(vis, false, sizeof(vis));
    44         for(int i = 1; i <= n; ++i) {
    45             scanf("%lld", &a);
    46             vec[a].push_back(i);
    47             vis[a] = true; // 标记出现的元素
    48         }
    49         for(LL i = 1LL; i < maxn; ++i) {
    50             num = 0;
    51             for(LL j = i; j < maxn && num < 2; j += i) {
    52                 if(!vis[j]) continue;
    53                 if(num == 0) { // 第一次出现
    54                     siz = vec[j].size();
    55                     if(siz == 1) {
    56                         ++num;
    57                         p1 = vec[j][0];
    58                         now1 = j;
    59                     }
    60                     else {
    61                         num += 2; // 头2个
    62                         p1 = vec[j][0], p2 = vec[j][1];
    63                         now1 = j, now2 = j;
    64                     }
    65                 }else { // 第二次出现
    66                     ++num;
    67                     now2 = j;
    68                     p2 = vec[j][0];
    69                 }
    70             }
    71             if(num == 2) {
    72                 now0 = now1 / i * now2;
    73                 if(ans > now0) {
    74                     ans = now0;
    75                     per1 = p1, per2 = p2;
    76                 }
    77             }
    78         }
    79         if(per1 > per2) swap(per1, per2);
    80         printf("%d %d
    ", per1, per2);
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    hadoop 动态调整mapred参数
    python 遍历hadoop, 跟指定列表对比 包含列表中值的取出。
    replay的意义
    c++ 异常 warning: 'MEMORY_UNIT_NAME' defined but not used
    c++ 异常 discards qualifiers 丢弃
    c++ 条件变量
    声明
    HibernateSessionFactory建立-使用ThreadLocal
    App Crawler使用教程
    loadrunner生成随机数用于Action参数中
  • 原文地址:https://www.cnblogs.com/acgoto/p/10725576.html
Copyright © 2011-2022 走看看