hdu4841---圓桌問題解題報告(約瑟夫環問題---陣列,queue,vector三種實現方式)
阿新 • • 發佈:2018-11-05
圓桌問題連結
輸入: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; }