1. 程式人生 > >hdu4841---圓桌問題解題報告(約瑟夫環問題---陣列,queue,vector三種實現方式)

hdu4841---圓桌問題解題報告(約瑟夫環問題---陣列,queue,vector三種實現方式)

                                            圓桌問題連結

輸入:n(好人數,壞人數),m(數到m殺人,接著從1開始數)

輸出:G為好人,B為壞人,壞人全部會在被殺的位置。

三種實現方式:

1.最樸素的陣列:(模擬整個過程)

#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<list>
#define mod 998244353
#define INF 0x3f3f3f3f
#define Min 0xc0c0c0c0
#define mst(a) memset(a,0,sizeof(a))
#define f(i,a,b) for(int i = a; i < b; i++)
using namespace std;
typedef long long ll;
const int MAX_N = 32767;
bool vis[2 * MAX_N];
int main(){
    //freopen("c1.txt", "w", stdin);
    //freopen("c2.txt", "r", stdout);
    //ios::sync_with_stdio(false);
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        for(int i = 1; i <= 2 * n; i++){
            vis[i] = true;
        }
        int sum = 2 * n;
        int cur = 0;
        while(sum > n){
            for(int i = 1; i <= 2 * n; i++){
                if(!vis[i]){
                    continue;
                }
                if(sum <= n){    //這裡的判斷尤其重要,不然殺人數可能會超過n
                    break;
                }
                cur++;
                if(cur == m){
                    vis[i] = false;
                    cur = 0;
                    sum--;
                }
            }
        }
        for(int i = 1; i <= 2 * n; i++){
            if(!vis[i]){
                printf("B");
            }
            else {
                printf("G");
            }
            if(i % 50 == 0) printf("\n");
        }
        printf("\n\n");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

2.佇列實現,明顯方便很多,什麼預判都不用想,直接寫。

#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<list>
#define mod 998244353
#define INF 0x3f3f3f3f
#define Min 0xc0c0c0c0
#define mst(a) memset(a,0,sizeof(a))
#define f(i,a,b) for(int i = a; i < b; i++)
using namespace std;
typedef long long ll;
const int MAX_N = 32767;
bool vis[2 * MAX_N];
int main(){
    //freopen("c1.txt", "w", stdin);
    //freopen("c2.txt", "r", stdout);
    //ios::sync_with_stdio(false);
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        queue<int> q;
        for(int i = 1; i <= 2 * n; i++){
            q.push(i);
            vis[i] = false;
        }
        int cur = 0;
        while(q.size() > n){
            cur++;
            int x = q.front();
            if(cur == m){
                cur = 0;
                q.pop();
                vis[x] = true;
            }
            else {
                q.pop();
                q.push(x);
            }
        }
        for(int i = 1; i <= 2 * n; i++){
            if(vis[i]){
                printf("B");
            }
            else {
                printf("G");
            }
            if(i % 50 == 0){
                printf("\n");
            }
        }
        printf("\n\n");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

3.vector(出於學習的角度寫的),vector的i必須從0開始,由於不熟練,寫的過程WA了好幾次

#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<list>
#define mod 998244353
#define INF 0x3f3f3f3f
#define Min 0xc0c0c0c0
#define mst(a) memset(a,0,sizeof(a))
#define f(i,a,b) for(int i = a; i < b; i++)
using namespace std;
typedef long long ll;
const int MAX_N = 32767;
bool vis[2 * MAX_N];
int main(){
    //freopen("c1.txt", "w", stdin);
    //freopen("c2.txt", "r", stdout);
    //ios::sync_with_stdio(false);
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        mst(vis);
        vector<int> v(2 * n);
        for(int i = 0; i < 2 * n; i++){    //vector陣列只能從0開始填充
            v[i] = i;
        }
        int cur = 0;
        while(v.size() > n){
            cur = (cur + m - 1) % v.size();    //vector陣列中被殺那個人的位置
            vis[v[cur]] = 1;                //記錄這個人開始的位置
            v.erase(v.begin() + cur);        //清除該位置的人
        }
        for(int i = 0; i < 2 * n; i++){
            if(vis[i]){
                printf("B");
            }
            else {
                printf("G");
            }
            if( (i + 1) % 50 == 0){
                printf("\n");
            }
        }
        printf("\n\n");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}