zoukankan      html  css  js  c++  java
  • newcoder F石头剪刀布(DFS + 思维)题解

    题意:
    wzms 今年举办了一场剪刀石头布大赛,bleaves 被选为负责人。
    比赛共有 2n 个人参加, 分为 n 轮,
    在每轮中,第 1 位选手和第 2 位选手对战,胜者作为新的第 1 位选手,
    第 3 位和第 4 位对战,胜者作为新的第 2 位选手,以此类推。
    bleaves 调查得知,每个人都有其偏爱决策,每个人在每一次对战中都会使用他的偏爱决策。
    如果一次对战的双方的偏爱决策相同,那么这次对战就永远不会结束,所以 bleaves 不希望这种情况发生。
    现在 bleaves 知道了每个人的偏爱决策,但她不知道如何安排初始的次序,使得上面的情况不会发生,你能帮帮她吗?

    全部的输入数据满足:R+P+S=2n ,1n20

    链接:https://ac.nowcoder.com/acm/contest/332/F

    来源:牛客网

    思路:正向思考好像有点难度,那么就反向思考。只要确定了最终胜出的人,那么前面的都能推出来了,那么就从最后往前递归,然后从末尾往前按字典序排序递归回来。

    代码:

    #include<set>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int maxn = (1 << 21) + 10;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    int R, P, S, cnt;
    int r, p, s;
    char ans[maxn];
    void dfs(char x, int L, int R){
        if(L == R){
            ans[L] = x;
            if(x == 'R') r++;
            else if(x == 'P') p++;
            else if(x == 'S') s++;
            return;
        }
        int m = (L + R) >> 1;
        if(x == 'R'){
            dfs('R', L, m);
            dfs('S', m + 1, R);
        }
        else if(x == 'P'){
            dfs('P', L, m);
            dfs('R', m + 1, R);
        }
        else if(x == 'S'){
            dfs('S', L, m);
            dfs('P', m + 1, R);
        }
        bool swapp = false;
        for(int i = L; i <= m; i++){
            if(ans[i] < ans[m + i - L + 1]) break;
            if(ans[i] > ans[m + i - L + 1]){
                swapp = true;
                break;
            }
        }
        if(swapp){
            for(int i = L; i <= m; i++){
                swap(ans[i], ans[m + i - L + 1]);
            }
        }
    }
    int main(){
        scanf("%d%d%d", &R, &P, &S);  //r p s
        cnt = R + P + S;
        bool flag = false;
        for(int i = 0; i < 3; i++){
            r = p = s = 0;
            if(i == 0){
                dfs('R', 1, cnt);
            }
            else if(i == 1){
                dfs('P', 1, cnt);
            }
            else if(i == 2){
                dfs('S', 1, cnt);
            }
            if(R == r && P == p && S == s){
                flag = true;
                break;
            }
        }
        ans[cnt + 1] = '';
        if(flag) printf("%s
    ", ans + 1);
        else printf("IMPOSSIBLE
    ");
        return 0;
    }
  • 相关阅读:
    ScrollView 字典
    centos 6.x 安装redis
    Linux 添加epel源
    Linux 关于解压
    Linux 删除文件夹
    Linux sz rz
    让div 实现 input效果
    解决js浮点数计算bug
    键盘绑定事件和焦点处理
    npm的镜像替换成淘宝
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10353215.html
Copyright © 2011-2022 走看看