cf比赛记录Codeforces Round #601 (Div. 2)
Posted ayanowww
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf比赛记录Codeforces Round #601 (Div. 2)相关的知识,希望对你有一定的参考价值。
Codeforces Round #601 (Div. 2) ---- 比赛传送门
周二晚因为身体不适鸽了,补题补题
A
// http://codeforces.com/contest/1255/problem/A
/*
签到题 简单的贪心题
本考虑过是否有先小于再加上去会更小的情况
但两种情况恰好步数是一样的
*/
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int T;
int a, b;
int num[] = { 5, 2, 1 };
int main()
{
scanf("%d", &T);
while(T--){
scanf("%d %d", &a, &b);
int ans = 0, tmp, i = 0;
if(a != b){
tmp = abs(a - b);
while(tmp){
int div = tmp / num[i];
ans += div;
tmp -= num[i] * div;
i++;
}
}
printf("%d
", ans);
}
return 0;
}
B
// http://codeforces.com/contest/1255/problem/B
/*
图形...
既然 m <= n 的话,要满足题目的要求就只能 m == n 了
那既然如此......把冰箱都连成环就 Ok 了
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int T, n, m;
int main()
{
scanf("%d", &T);
while(T--){
scanf("%d %d", &n, &m);
int a, tot = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &a); tot += a;
}
if(n < 3 || m != n) printf("-1
"); // 特判:当出现这种情况时,是肯定不符合的
else {
printf("%d
", tot * 2);
for(int i = 1; i <= n; i++){
printf("%d %d
", i, i % n + 1);
}
}
}
return 0;
}
C
// http://codeforces.com/contest/1255/problem/C
/*
找规律 ---- 拓扑排序
首尾的数是最好找的,因为只会出现一次
根据样例分析
5
4 3 2
2 3 5
4 1 2
依次出现的次数
1:1 2:3 3:2 4:2 5:1
可见, 1, 5各只出现了 1 次 因此首尾分别是 1 5,然后 2 出现了 3 次 所以 2 是中间数
然后 3 4 就可以根据 1 2 的收尾排序就可以确认了
1 4 2 3 5
或者
5 3 2 4 1
因此,每次找 tot[] 为 1 的数加进首跟尾
要提前记录每个点所在的 arr 位置(减少查找时的时间)
----拓扑排序
但由于自己实现太繁琐,所以没实现出来就去找AC的代码,发现了dalao的凝练版
----参考了 yongwhan dalao的代码,#65412415
*/
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n;
int a, b, c;
int tot[100005];
bool used[100005];
vector<int> num[100005];
/*
对该代码的分析:
因为每组只有3个数
所以对于样例 1 4 2 3 5 这组数据
1 的相邻有 4 2
4 的相邻有 1 2 3
2 的相邻有 1 4 3 5
...
先找出 1 (这个很好找)
找出 1 后可以确立第二个数是 4 (因为 4 只出现了两次,而 2 出现了 3 次)
然后从 1 开始找 "下一个数", 此时与 1 相邻的只有 2 了 ---- 输出,并记录其已被使用
接着从 4 开始找还未被使用过且相邻的数,于是进而找到 3
接着从 2 开始找,接着就找到了 5
即便 n > 5 这样的方法也是成立的,如
n = 7; 排序是 3 2 1 7 6 5 4
先找到 3 2
然后从 3 开始找,相邻的还没用的就只剩下 1
接着从 2 开始找,同理还剩下 7
继续从 1 开始找,同理还剩下 6
继续从 7 开始找,剩下 5
最后从 6 开始找,最后的是 4
...
所以dalao的代码还是tql
*/
int main()
{
scanf("%d", &n);
for(int i = 0; i < n - 2; i++){
scanf("%d %d %d", &a, &b, &c);
num[a].push_back(b); num[a].push_back(c);
num[b].push_back(a); num[b].push_back(c);
num[c].push_back(a); num[c].push_back(b);
tot[a]++; tot[b]++; tot[c]++;
}
int x, y, z;
for(int i = 1; i <= n; i++){
if(tot[i] == 1){
x = i;
break;
}
}
if(tot[num[x][0]] == 2) y = num[x][0];
else y = num[x][1];
used[x] = used[y] = true;
printf("%d %d ", x, y);
// 以下的注释可以去掉输出看看更方便理解...
for(int i = 1; i <= n - 2; i++){
// printf("
x:%d
", x);
for(int j = 0; j < num[x].size(); j++){ // 找到相邻且未被使用过的点
// printf("j:%d num[x][]:%d used:%d
", j, num[x][j], used[num[x][j]]);
if(!used[num[x][j]]) { // 由于特殊性,这个点只有 1 个
z = num[x][j];
// printf("z:%d
", z); // 从这里看出,每次这么进行的时候 z 只改变了一次
}
}
used[z] = true;
printf("%d ", z);
x = y; y = z;
}
return 0;
}
// 下面是我自己敲的臃肿代码 思想是运用拓扑排序加优化 结果把自己绕晕了
//#include<iostream>
//#include<cstdio>
//#include<stack>
//#include<vector>
//#include<algorithm>
//#include<queue>
//#include<stack>
//using namespace std;
//
//int n;
//struct jilu{
// int tot, who;
//}cot[100005]; // tot 记录 who 出现了多少次;
//struct node{
// int a, b, c;
//}arr[100005];
//bool used[100005]; // 记录哪个arr已经被用过
//vector<int> tmp[100005]; // 记录数字 i 所在输入数组里的位置
//queue<int> take; // 本次进行了减减的数
//stack<int> ans2;
//queue<int> ans1;
//
//bool cmp(jilu a, jilu b){
// if(a.tot == b.tot) return a.who < b.who;
// return a.tot < b.tot;
//}
//
//
//int main()
//{
// scanf("%d", &n);
// for(int i = 1; i <= n - 2; i++){
// scanf("%d %d %d", &arr[i].a, &arr[i].b, &arr[i].c);
// cot[arr[i].a].tot++; cot[arr[i].b].tot++; cot[arr[i].c].tot++;
// cot[arr[i].a].who = arr[i].a;
// cot[arr[i].b].who = arr[i].b;
// cot[arr[i].c].who = arr[i].c;
// tmp[arr[i].a].push_back(i);
// tmp[arr[i].b].push_back(i);
// tmp[arr[i].c].push_back(i);
// }
//
// sort(cot + 1, cot + n + 1, cmp);
//
// ans1.push(cot[1].who); ans2.push(cot[2].who);
// for(int i = 0; i < tmp[cot[1].who].size(); i++){ // 首的初始化
// cot[cot[1].who].tot--;
// int p = tmp[cot[1].who][i];
// used[p] = true;
// if(arr[p].a != cot[1].who) {
// cot[arr[p].a].tot--;
// take.push(arr[p].a);
// }
// if(arr[p].b != cot[1].who) {
// cot[arr[p].b].tot--;
// take.push(arr[p].b);
// }
// if(arr[p].c != cot[1].who) {
// cot[arr[p].c].tot--;
// take.push(arr[p].c);
// }
// }
//
// for(int i = 0; i < tmp[cot[2].who].size(); i++){ // 尾的初始化
// cot[cot[2].who].tot--;
// int p = tmp[cot[2].who][i];
// used[p] = true;
// if(arr[p].a != cot[2].who) {
// cot[arr[p].a].tot--;
// take.push(arr[p].a);
// }
// if(arr[p].b != cot[2].who) {
// cot[arr[p].b].tot--;
// take.push(arr[p].b);
// }
// if(arr[p].c != cot[2].who) {
// cot[arr[p].c].tot--;
// take.push(arr[p].c);
// }
// }
//
// while(!take.empty()){
// ...
// }
//
// return 0;
//}
D
// http://codeforces.com/contest/1255/problem/D
// 参考:HazemAk1 的 #65396404 的 AC 代码
/*
要使 k 头奶牛在点上取得的 R 尽量均匀 ---- 即最大与最小的差 <= 1
要求每头牛所占的 R 的数目很简单
关键是处理图的连块问题
搜索
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const char out[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 62种输出情况
int T, H, W, k, R, now;
char maze[102][102];
char ans[102][102];
int have[70];
//bool used[102][102];
//struct node{
// int h, w;
//};
//queue<node> q;
//int dw[] = { 1, 0, -1, 0 };
//int dh[] = { 0, 1, 0, -1 };
void solve(){
int x = 0, y = 0;
for(int i = 0; i < k; i++){
while((have[i] || i == k - 1) && x < H){ // 当还没选够选够或者是最后一头牛的时候就继续进行, x 还没到达最大行的时候继续进行
ans[x][y] = out[i]; // 既然还没有找完 那该点就是当前牛的位置啦
if(maze[x][y] == 'R') have[i]--; // 如果有一饭点就减减
if(x % 2 == 0){ // 当此时为偶数行的时候就从左往右遍历(因为是从0开始)
y++;
if(y > W - 1) x++, y = W - 1; // 下一行操作
}
else { // 同理 当此时为奇数行的时候就从右往左遍历
y--;
if(y < 0) x++, y = 0; // 下一行操作
}
}
}
}
int main()
{
scanf("%d", &T);
while(T--){
R = 0; // 记录总的R点数
memset(used, false, sizeof(used));
scanf("%d %d %d", &H, &W, &k);
for(int i = 0; i < H; i++){
scanf("%s", maze[i]);
for(int j = 0; j < W; j++){
if(maze[i][j] == 'R') R++;
}
}
// 给每头牛所占有的R点个数赋值
int l = R / k;
int lea = R - k * l;
for(int i = 0; i < k; i++){
have[i] = l + (lea > 0);
lea--;
}
solve();
// 输出
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
printf("%c", ans[i][j]);
}
printf("
");
}
// 以下是我自己写的方法,繁杂,不利索
// now = 0;
// for(int i = 0; i < H; i++){
// for(int j = 0; j < W; j++){
// if(!used[i][j]){
////// printf("now:%d
", now);
//// used[i][j] = true;
//// if(maze[i][j] == 'R') have[now]--;
////// printf("h:%d w:%d have:%d
", i, j, have[now]);
//// q.push({i, j});
//// bfs();
//// now++;
// dfs(i, j, now, have[now]);
// }
// }
// }
}
return 0;
}
//bfs 也绕晕了自己
//void bfs(){
// bool flag = false;
// while(!q.empty()){
// node n = q.front(); q.pop();
// ans[n.h][n.w] = out[now];
//
// for(int i = 0; i < 4; i++){
// int nh = n.h + dh[i]; int nw = n.w + dw[i];
// if(0 <= nh && nh < H && 0 <= nw && nw < W && !used[nh][nw] && (now == k - 1 || !flag)){
// used[nh][nw] = true;
// q.push({nh, nw});
// if(maze[nh][nw] == 'R'){
//// printf("now:%d nh:%d nw:%d maze:%c
", now, nh, nw, maze[nh][nw]);
// have[now]--;
// if(have[now] == 0 && now != k - 1){
// flag = true;
// }
// }
// }
// }
// }
//}
// 我这个 dfs 有坑
//void dfs(int h, int w, int &now, int &tot){
// used[h][w] = true;
// ans[h][w] = out[now];
// if(maze[h][w] == 'R'){
// tot--;
// maze[h][w] = '.';
// if(tot == 0 && now != k - 1){
// now++;
// return ;
// }
// }
//
// for(int i = 0; i < 4; i++){
// int nh = h + dh[i]; int nw = w + dw[i];
// if(0 <= nh && nh < H && 0 <= nw && nw < W && !used[nh][nw]){
// dfs(nh, nw, now, tot);
// if(tot == 0) return ;
// }
// }
//}
因为没有打比赛所以就没有这次的rating啦w
以上是关于cf比赛记录Codeforces Round #601 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
cf比赛记录Educational Codeforces Round 78 (Rated for Div. 2)
cf比赛记录Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
比赛记录[Educational Codeforces Round 79 (Rated for Div. 2)]
cf之路,1,Codeforces Round #345 (Div. 2)