zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    Kafka项目实践
    页级别的恢复
    Linux查看网卡流量(转)
    Linux Top 命令解析 比较详细(转)
    《神秘的程序员们》漫画26~28:《万年坑系列》 I、II、III(转)
    Linux概念架构的理解(转)
    Building Redis for use on Cygwin(转)
    2014值得期待的Erlang两本新书
    jps命令使用
    编译原理学习导论
  • 原文地址:https://www.cnblogs.com/Ayanowww/p/11914963.html
Copyright © 2011-2022 走看看