@Dmaxiya
2018-08-17T02:18:52.000000Z
字数 5331
阅读 1232
Codeforces
Contests 链接:Educational Codeforces Round 37
过题数:3
排名:763/9623
有 个花圃排成一排,从 到 编号,有 个喷头放在这 个花圃中的 处,这个喷头开启后第 秒会将 处的花圃淋湿,第 秒会将区间 内的所有花圃淋湿,且只有整数秒时才会淋湿一个花圃,问所有喷头同时开启,最少多少秒可以将所有花圃淋湿。
第一行为一个整数 ,接下来有 组数据,每组数据的第一行为两个整数 ,第二行有 个整数 ,表示第 个喷头的位置为 。
输出最少让所有花圃淋湿的时间。
| 输入 | 输出 | 提示 |
|---|---|---|
| 3 5 1 3 3 3 1 2 3 4 1 1 |
3 1 4 |
1.在第一组数据中,第 秒的时候第 个花圃会被淋湿,第 秒的时候区间 内的花圃会 被淋湿,第 秒的时候所有的花圃都会被淋湿; 2.在第二组数据中,每一个花圃上都有一个喷头,因此在第 秒的时候所有的花圃就都会被淋湿; 3.在第三组数据中,只有第 个花圃有喷头,所以需要 秒时间将所有花圃淋湿。 |
计算所有相邻喷头中间位置的花圃被淋到的时间,以及边缘的花圃会被淋到的时间,取最大值。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#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 = 200 + 100;int T, n, k, ans;int num[maxn];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);scanf("%d", &T);while(T--) {scanf("%d%d", &n, &k);ans = 0;for(int i = 1; i <= k; ++i) {scanf("%d", &num[i]);}for(int i = 2; i <= k; ++i) {ans = max(ans, (num[i] - num[i - 1]) / 2 + 1);}ans = max(ans, num[1]);ans = max(ans, n - num[k] + 1);printf("%d\n", ans);}return 0;}
有 个学生,第 个学生将会在第 秒来等待接茶水,每个人接茶水消耗的时间为 ,如果两个学生同时到达,则编号小的同学排在队伍的前面,如果某个同学到达时前面有同学在等待,他也会排队等待,如果超过 秒仍然没有轮到他接茶水,他就会马上离开,求每个同学接到茶水的时间。
第一行为一个整数 ,接下去有 组数据,每组数据第一行为一个整数 ,接下去有 行,每一行有两个整数 ,对于所有的 ,都有 。且所有数据的 的和不超过 。
每一组数据输出一行 个整数,第 个整数代表第 个学生接到茶水的时间,如果某个学生没有接到茶水直接离开,则输出 。
| 输入 | 输出 | 提示 |
|---|---|---|
| 2 2 1 3 1 4 3 1 5 1 1 2 3 |
1 2 1 0 2 |
1.对于第 组数据, 个学生同时到达,第 个学生在第 秒接到茶水, 第 个学生在第 秒接到茶水。 2.对于第 组数据,第 个和第 个学生同时到达,第 个学生在第 秒接到茶水,第 秒结束第二个学生没有接到茶水就离开了,第 秒时 第 个学生到达,并接到茶水。 |
按照题意模拟。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#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 = 1000 + 100;int T, n, l, r;int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);scanf("%d", &T);while(T--) {int now = 0;scanf("%d", &n);for(int i = 0; i < n; ++i) {scanf("%d%d", &l, &r);now = max(now, l);if(i != 0) {printf(" ");}if(now > r) {printf("0");} else {printf("%d", now);++now;}}printf("\n");}return 0;}
给定一个长度为 的序列,在这个序列中的某些位置 可以和第 个位置的数字进行交换,问能否通过任意次合法的交换,使得这个数列成为一个递增数列。
第一行为一个整数 ,第二行为 个整数 ,第三行为一个字符串 ,字符串的第 位为 表示序列中的第 个数字可以和第 个数字交换位置。
如果可以在给定的条件下,通过任意次交换得到一个递增的数列,则输出 ,否则输出 。
| 输入 | 输出 | 提示 |
|---|---|---|
| 6 1 2 5 3 4 6 01110 |
YES | 可以通过交换 和 ,使数列成为一个递增的数列。 |
| 6 1 2 5 3 4 6 01010 |
NO |
能否通过交换使数列有序,即询问所有数字能否通过交换从排序前的下标移动到排序后的下标,即排序前后所有数字的下标都必须由 连通,就可以用并查集来判了。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#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 = 200000 + 100;int n;int num[maxn], Index1[maxn], Index2[maxn];int fa[maxn];char str[maxn];int Find(int x) {return (x == fa[x]? x: fa[x] = Find(fa[x]));}void unit(int x, int y) {int xx = Find(x);int yy = Find(y);fa[xx] = yy;}int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d", &n) != EOF) {for(int i = 1; i <= n; ++i) {scanf("%d", &num[i]);fa[i] = i;Index1[num[i]] = i;}sort(num + 1, num + 1 + n);for(int i = 1; i <= n; ++i) {Index2[num[i]] = i;}scanf("%s", str + 1);for(int i = 1; i < n; ++i) {if(str[i] == '1') {unit(i, i + 1);}}bool flag = true;for(int i = 1; i <= n; ++i) {if(Find(Index1[num[i]]) != Find(Index2[num[i]])) {flag = false;break;}}if(flag) {printf("YES\n");} else {printf("NO\n");}}return 0;}
一个 个节点的无向图的补图上有 条边,输出原图上所有连通块中节点的数量。
第一行为两个整数 ,接下去 行每行两个整数 ,表示原图上 与 之间没有连边。
第一行输出一个整数 ,表示连通块的个数,第二行按照非递减的顺序输出每个连通块内的节点数量。
| 输入 | 输出 |
|---|---|
| 5 5 1 2 3 4 3 2 4 2 2 5 |
2 1 4 |
用一个 来存所有没有被访问过的节点,每访问一个节点就从 中删去,直到所有节点都被访问( 为空),就可以得到所有连通块的信息,用 判连通块。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#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 = 200000 + 100;int n, m, u, v, cnt;set<int> st;set<int> G[maxn];int ans[maxn];queue<int> que;set<int>::iterator it;vector<set<int>::iterator> vct;int bfs(int x) {int ret = 1;while(!que.empty()) {que.pop();}que.push(x);st.erase(x);while(!que.empty()) {if(st.empty()) {return ret;}vct.clear();int tmp = que.front();que.pop();for(it = st.begin(); it != st.end(); ++it) {if(G[tmp].find(*it) == G[tmp].end()) {que.push(*it);vct.push_back(it);++ret;}}int len = vct.size();for(int i = 0; i < len; ++i) {st.erase(vct[i]);}}return ret;}int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d%d", &n, &m) != EOF) {cnt = 0;st.clear();for(int i = 1; i <= n; ++i) {G[i].clear();st.insert(i);}for(int i = 0; i < m; ++i) {scanf("%d%d", &u, &v);G[u].insert(v);G[v].insert(u);}while(!st.empty()) {ans[cnt++] = bfs(*(st.begin()));}sort(ans, ans + cnt);printf("%d\n", cnt);for(int i = 0; i < cnt; ++i) {if(i != 0) {printf(" ");}printf("%d", ans[i]);}printf("\n");}return 0;}