@Dmaxiya
2018-08-17T02:24:43.000000Z
字数 6999
阅读 1317
Codeforces
Contests 链接:Educational Codeforces Round 24
过题数:2
排名:902/5771
总共有 个学生,有一部分学生获得了 ,有另一部分学生获得了 ,而其他学生什么都没有获得,其中获得 与 的学生称为 ,问在保证 人数不超过 且 的条件下,获得使 最大的情况。
输入包含两个整数 。
分别输出获得 、 和什么都没获得的人数。
| 输入 | 输出 |
|---|---|
| 18 2 | 3 6 9 |
| 9 10 | 0 0 9 |
| 1000000000000 5 | 83333333333 416666666665 500000000002 |
| 1000000000000 499999999999 | 1 499999999999 500000000000 |
只要确定获得 的人数就可以确定另外两个人数,。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longLL n, k, ans;int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%I64d%I64d", &n, &k) != EOF) {ans = n / 2 / (k + 1);printf("%I64d %I64d %I64d\n", ans, ans * k, n - ans * (k + 1));}return 0;}
构造一个 的排列 ,使得对于一个长度为 的序列 ,当 时,总是满足 ,当 大于 时,将结果减去 。
第一行为两个整数 ,第二行为 个整数 。
如果无法构造出满足条件的序列,则输出 ,否则输出 个整数,如果有多解输出任意一组解。
| 输入 | 输出 | 提示 |
|---|---|---|
| 4 5 2 3 1 4 4 |
3 1 2 4 | 从 开始: |
| 3 3 3 1 2 |
-1 |
首先根据 先生成一个 序列,先计算这个序列中每个数字出现的次数,如果某个数字出现的次数大于 ,则这个序列是非法的,接着将这个序列中没有被用到的数据放进去,使得 序列成为一个 的排列,最后再扫一遍 序列,判断是否对于每个 都满足题给条件。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 100 + 100;int n, m;int num[maxn], ans[maxn], cnt[maxn];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d%d", &n, &m) != EOF) {memset(cnt, 0, sizeof(cnt));memset(ans, 0, sizeof(ans));for(int i = 1; i <= m; ++i) {scanf("%d", &num[i]);}for(int i = 1; i < m; ++i) {int tmp = num[i + 1] - num[i];tmp = (tmp % n + n) % n;if(tmp == 0) {tmp = n;}ans[num[i]] = tmp;}bool flag = true;for(int i = 1; i <= n; ++i) {if(ans[i] == 0) {continue;}++cnt[ans[i]];if(cnt[ans[i]] == 2) {flag =false;break;}}if(!flag) {printf("-1\n");continue;}for(int i = 1; i <= n; ++i) {if(ans[i] == 0) {for(int j = 1; j <= n; ++j) {if(cnt[j] == 0) {++cnt[j];ans[i] = j;break;}}}}for(int i = 1; i < m; ++i) {int tmp = num[i] + ans[num[i]];tmp = (tmp % n + n) % n;if(tmp == 0) {tmp = n;}if(tmp != num[i + 1]) {flag = false;break;}}if(!flag) {printf("-1\n");continue;}for(int i = 1; i <= n; ++i) {if(i != 1) {printf(" ");}printf("%d", ans[i]);}printf("\n");}return 0;}
在一个 的仓库里,有 个沙发,每个沙发占两个相邻的位置,用两个坐标 表示,对于两个沙发 和 ,如果存在 ,则表示 沙发在 沙发的左边,如果存在 ,则表示 沙发在 沙发的右边,如果存在 ,则表示 沙发在 沙发的上面,如果存在 ,则表示 沙发在 沙发的下面,其中 分别属于沙发 与沙发 的其中一个横坐标或纵坐标。注意对于两个沙发, 可能既在 的左边也在 的右边。
现在给出某个沙发的左边、右边、上面、下面各有多少个沙发,找出满足条件的沙发。
第一行包含一个整数 ,第二行为两个整数 ,接下去 行,每行四个整数 ,表示每个沙发的坐标,数据保证任意两个坐标都不会相同,且对同一个沙发的坐标描述一定是相邻的。最后一行为四个整数 ,表示要找的沙发需要符合的四个方向的沙发数量。数据保证最多只有一个沙发符合条件。
如果不存在满足条件的沙发,就输出 ,否则输出满足条件的沙发编号,沙发编号按照输入顺序从 到 编号。
| 输入 | 输出 | 提示 |
|---|---|---|
| 2 3 2 3 1 3 2 1 2 2 2 1 0 0 1 |
1 | |
| 3 10 10 1 2 1 1 5 5 6 5 6 4 5 4 2 1 2 0 |
2 | · 第一个沙发的左边没有任何沙发,右边有两个沙发,上面没有沙发,下面有两个沙发; · 对于第二个沙发:; · 对于第三个沙发:; 因此第 个沙发满足给出的条件。 |
| 2 2 2 2 1 1 1 1 2 2 2 1 0 0 0 |
-1 | · 对于第一个沙发:; · 对于第二个沙发:; 没有沙发满足 。 |
假设第 个沙发的 ,由于上下左右四个方向的判定是类似的,因此这里只讨论左边的情况,可以推广到另外三个方向的情况:
由左边的判定方法可知:第 个沙发左边的沙发个数等于满足 的沙发个数(一个沙发只要有一个点满足条件,就能计入答案),我们可以通过对每个沙发的贡献做前缀和来 求出 。对于第 个沙发,它对所有满足 的沙发都有贡献,因此可以在 处标记一个 ,最后做一个前缀和即可查询到任意一个沙发左边的沙发个数。
对其他三个方向也做同样的判断。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 100000 + 100;int d, n, m, ans;int node[maxn][4], cnt[4];int Sum[4][maxn], Ends[4][2], dx[4];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d", &d) != EOF) {ans = -1;memset(Sum, 0, sizeof(Sum));scanf("%d%d", &n, &m);dx[0] = dx[2] = 1;dx[1] = dx[3] = -1;Ends[0][1] = n + 1;Ends[1][0] = n - 1;Ends[2][1] = m + 1;Ends[3][0] = m - 1;Ends[1][1] = Ends[3][1] = 0;Ends[0][0] = Ends[2][0] = 2;for(int i = 1; i <= d; ++i) {for(int j = 0; j < 4; ++j) {scanf("%d", &node[i][j]);}swap(node[i][1], node[i][2]);if(node[i][0] < node[i][1]) {swap(node[i][0], node[i][1]);}if(node[i][2] < node[i][3]) {swap(node[i][2], node[i][3]);}++Sum[0][node[i][1] + 1];++Sum[1][node[i][0] - 1];++Sum[2][node[i][3] + 1];++Sum[3][node[i][2] - 1];}for(int i = 0; i < 4; ++i) {for(int j = Ends[i][0]; j != Ends[i][1]; j += dx[i]) {Sum[i][j] += Sum[i][j - dx[i]];}}for(int i = 0; i < 4; ++i) {scanf("%d", &cnt[i]);}for(int i = 1; i <= d; ++i) {bool flag = true;for(int j = 0; j < 4; ++j) {int tmp = Sum[j][node[i][j]];if(node[i][j] != node[i][j ^ 1]) {--tmp;}if(tmp != cnt[j]) {flag = false;break;}}if(flag) {ans = i;break;}}printf("%d\n", ans);}return 0;}
和 两个人在车里可以看到窗外一辆辆行驶过的车,每辆车都有一个颜色 , 和 最开始分别选一种颜色 和 ,每经过一辆车,就统计到目前为止颜色为 的车的数量 和颜色为 的车的数量 ,对于经过的每一辆车:
- 如果 ,则 获胜;
- 如果 ,则 获胜;
- 否则两人平局。
知道将要经过的每一辆车的颜色,现在 已经选择了一种颜色 ,问 应该选择什么颜色才能获胜?
第一行包含两个整数 ,第二行包含 个整数 。
如果 可以获胜,则输出他应该选择的颜色 ,否则输出 。数据保证如果 可以获胜,那么在 内一定存在一种颜色可以使 获胜,如果有多解输出任意一组。
| 输入 | 输出 |
|---|---|
| 4 1 2 1 4 2 |
2 |
| 5 2 2 2 4 5 3 |
-1 |
| 3 10 1 2 3 |
4 |
首先将所有颜色都作为可能的答案,每出现一种颜色,就将这种颜色的出现次数 ,接着将所有出现次数小于 的数字删除,最后剩下来的的颜色就是答案,如果最后没有数字留下,则输出 。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 1000000 + 100;struct Node {int cnt, num;Node() {}Node(int c, int n) {cnt = c;num = n;}};bool operator<(const Node &a, const Node &b) {return (a.cnt == b.cnt? a.num < b.num: a.cnt > b.cnt);}int n, A, c;bool vis[maxn];int cnt[maxn];set<Node> st;set<Node>::iterator it;vector<set<Node>::iterator> vct;int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d%d", &n, &A) != EOF) {st.clear();memset(cnt, 0, sizeof(cnt));memset(vis, 0, sizeof(vis));for(int i = 1; i <= 1000000; ++i) {st.insert(Node(0, i));}for(int i = 0; i < n; ++i) {scanf("%d", &c);if(vis[c]) {continue;}it = st.find(Node(cnt[c], c));st.erase(it);++cnt[c];st.insert(Node(cnt[c], c));it = st.upper_bound(Node(cnt[A] - 1, 0));vct.clear();for(; it != st.end(); ++it) {vct.push_back(it);}int len = vct.size();for(int i = 0; i < len; ++i) {vis[vct[i]->num] = true;st.erase(vct[i]);}}st.erase(Node(cnt[A], A));if(st.empty()) {printf("-1\n");continue;}it = st.begin();printf("%d\n", it->num);}return 0;}