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 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4117711.html