zoukankan      html  css  js  c++  java
  • CodeForces Round #279 (Div.2)

    A:

    题意:

    有三个项目和n个学生,每个学生都擅长其中一个项目,现在要组成三个人的队伍,其中每个人恰好擅长其中一门,问能组成多少支队伍。

    分析:

    最多能组成的队伍的个数就是擅长项目里的最少学生。

     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 int main(void)
     8 {
     9     int n, x;
    10     vector<int> a[4];
    11     scanf("%d", &n);
    12     for(int i = 1; i <= n; ++i)
    13     {
    14         scanf("%d", &x);
    15         a[x].push_back(i);
    16     }
    17     int aa = a[1].size(), bb = a[2].size(), cc = a[3].size();
    18     int ans = min(aa, bb);
    19     ans = min(ans, cc);
    20     printf("%d
    ", ans);
    21     for(int i = 0; i < ans; ++i)
    22         printf("%d %d %d
    ", a[1][i], a[2][i], a[3][i]);
    23     
    24     return 0;
    25 } 
    代码君

    B:

    题意:

    有n个学生排成一队,他们有各自的学号(学号互不相同),现在知道每名学生前面那个人的学号ai和后面同学的学号bi,没有前驱或后继的补0,给出的顺序是任意的。要求顺序输出这些学号。

    分析:

    显然0是我们的突破点。如果n是偶数,从a中的那个0开始往后面推我们能得到排在偶数为的学号,从b中的0往前推,能得到奇数位置的学号。

    n为奇数就略为棘手,不管从哪个0开始推,都只能得到偶数位置的学号。所以我们要另外分析奇数位置,发现:第一个学号是a、b中只出现一次且在a中的学号,找到这个头我们就可以往后面推了,当然如果找到的是b中只出现一次的那个尾也可以往前推。

    代码比较挫,还是贴上来吧,毕竟是自己的孩子啊。

     1 #include <cstdio>
     2 
     3 const int maxn = 1000000 + 10;
     4 int left[maxn], right[maxn], cnt[maxn], vis[maxn];
     5 int ans[maxn];
     6 
     7 int main(void)
     8 {
     9     //freopen("Bin.txt", "r", stdin);
    10     int n, a, b;
    11     scanf("%d", &n);
    12     for(int i = 0; i < n; ++i)
    13     {
    14         scanf("%d%d", &a, &b);
    15         right[a] = b;
    16         left[b] = a;
    17         cnt[a]++;
    18         cnt[b]++;
    19     }
    20     if(n % 2 == 0)
    21     {
    22         int t = 0;
    23         for(int i = 2; i <= n; i += 2)
    24         {
    25             ans[i] = right[t];
    26             t = right[t];
    27         }
    28         t = 0;
    29         for(int i = n-1; i >= 1; i -= 2)
    30         {
    31             ans[i] = left[t];
    32             t = left[t];
    33         }
    34     }
    35     else
    36     {
    37         int i, t = 0;
    38         for(i = 2; i <= n; i += 2)
    39         {
    40             ans[i] = right[t];
    41             vis[t] = 1;
    42             t = right[t];
    43         }
    44         for(i = 1; i <= maxn; ++i)
    45             if(cnt[i] == 1) break;
    46         t = i;
    47         if(left[t] == 0)
    48         {
    49             for(int i = 1; i <= n; i += 2)
    50             {
    51                 ans[i] = t;
    52                 t = right[t];
    53             }
    54         }
    55         else
    56         {
    57             for(int i = n; i >= 1; i -= 2)
    58             {
    59                 ans[i] = t;
    60                 t = left[t];
    61             }
    62         }
    63     }
    64     for(int i = 1; i < n; ++i) printf("%d ", ans[i]);
    65     printf("%d
    ", ans[n]);
    66     
    67     return 0;
    68 }
    代码君

    又去翻了翻牛牛们的代码,发现他没有分奇偶,直接输出的,只弄明白大意。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 const int MAXN = 200010;
     6 const int MAXA = 1000010;
     7 
     8 int nex[MAXN];
     9 int rb[MAXA], ra[MAXA];
    10 int a[MAXN], b[MAXN];
    11 
    12 int main()
    13 {
    14     //freopen("Bin.txt", "r", stdin);
    15     ios_base::sync_with_stdio(false);
    16     int n;
    17     cin >> n;
    18     int st = -1, stid = -1;
    19     for (int i = 1; i <= n; i++)
    20     {
    21         cin >> a[i] >> b[i];
    22         ra[a[i]] = i;
    23         rb[b[i]] = i;
    24         if (a[i] == 0)
    25             st = i;
    26     }
    27     for (int i = 1; i <= n; i++)
    28         if (rb[a[i]] == 0)
    29             stid = a[i];
    30     while (st != 0)
    31     {
    32         cout << stid << " ";
    33         int nid = b[st];
    34         st = ra[stid];
    35         stid = nid;
    36     }
    37     cout << endl;
    38 }
    高冷的代码君

    C: (高精度取模)

    题意:

    有一个大数s和两个int a、b,问是否能够将这个大数从中间分隔开,使得前面的数被a整除,后面的数被b整除,且不能有前导0。

    分析:

    从低位到高位计算低i位数模b的余数,然后从高位到低位计算高i位数模a的余数,如果有一个i的值满足前i位数被a整除后面的数被b整除且b不含前导0,这找到符合要求的分割,输出即可。

    s.substr(pos, len)是求s的从pos开始,长度为len的子串。

     1 #include <cstdio>
     2 #include <string>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 const int maxn = 1000000 + 10;
     7 int mas[maxn];
     8 
     9 int main()
    10 {
    11     //freopen("Cin.txt", "r", stdin);
    12     ios::sync_with_stdio(false);
    13     string s;
    14     int a, b;
    15     cin >> s >> a >> b;
    16     int tmp = 1;
    17     mas[s.size()] = 0;
    18     for(int i = (int)s.size()-1; i >= 0; --i)
    19     {
    20         mas[i] = mas[i+1] + tmp * (s[i] - '0');
    21         mas[i] = mas[i] % b;
    22         tmp *= 10;
    23         tmp = tmp % b;
    24     }
    25     
    26     tmp = 0;
    27     for(int i = 0; i < (int)s.size()-1; ++i)
    28     {
    29         tmp = tmp * 10 + (s[i] - '0');
    30         tmp %= a;
    31         if(tmp == 0 && s[i+1] != '0') //²»ÄÜÓÐÇ°µ¼0 
    32         {
    33             if(mas[i+1] == 0)
    34             {
    35                 cout << "YES
    ";
    36                 cout << s.substr(0, i+1) << "
    ";
    37                 cout << s.substr(i+1, s.size()-i-1) << "
    ";
    38                 return 0;
    39             }
    40         }
    41     }
    42     cout << "NO
    ";
    43     
    44     return 0;
    45 }
    代码君
  • 相关阅读:
    轻松学习Linux之AWK使用初步
    轻松学习Linux之理解Shell的硬链接与软连接
    轻松学习Linux之自动执行任务
    轻松学习Linux系统安装篇之fdisk命令行工具的使用
    Leetcode-1030 Next Greater Node In Linked List(链表中的下一个更大节点)
    Leetcode-1028 Convert to Base -2(负二进制转换)
    Leetcode-1029 Binary Prefix Divisible By 5(可被 5 整除的二进制前缀)
    ACM模板——2的次方表
    ACM模板——快速幂
    ACM模板——素数相关
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4117711.html
Copyright © 2011-2022 走看看