https://www.bnuoj.com/v3/contest_show.php?cid=9146#problem/G
【题意】
题意很简单,就是“鸽尾式”洗扑克,问洗m次各张牌的位置
【思路】
牌是有限的,所以这个置换一定是有周期的。s1和s2中固定位置总会被置换到Shuffle中的固定位置,比如s1中的1总会被置换到shuffle中的2,s1中的2总会被置换到shuffle中的4,我们只需要找出这个置换里的几个轮换。如第一个样例1->2->4->8->7->5->1
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<string> 6 #include<cstring> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef double db; 11 const int mod=1e8; 12 int n,m; 13 const int maxn=1e5+2; 14 char pk[maxn][5]; 15 int nxt[maxn]; 16 vector<int> cyc[maxn]; 17 int vis[maxn]; 18 int ans[maxn]; 19 int anss[maxn]; 20 int main() 21 { 22 int T; 23 scanf("%d",&T); 24 int cas=0; 25 while(T--) 26 { 27 memset(vis,0,sizeof(vis)); 28 memset(ans,0,sizeof(ans)); 29 memset(anss,0,sizeof(anss)); 30 scanf("%d%d",&n,&m); 31 for(int i=0;i<n;i++) 32 { 33 scanf("%s",pk[i]); 34 } 35 for(int i=0;i<(n+1)/2;i++) 36 { 37 nxt[i]=2*i; 38 } 39 for(int i=(n+1)/2;i<n;i++) 40 { 41 nxt[i]=2*(i-(n+1)/2)+1; 42 } 43 for(int i=0;i<n;i++) 44 { 45 cyc[i].clear(); 46 } 47 int cntc=0; 48 for(int i=0;i<n;i++) 49 { 50 if(!vis[i]) 51 { 52 cyc[cntc].push_back(i); 53 vis[i]=1; 54 int cur=i; 55 while(!vis[nxt[cur]]) 56 { 57 cur=nxt[cur]; 58 vis[cur]=1; 59 cyc[cntc].push_back(cur); 60 } 61 cntc++; 62 } 63 } 64 for(int i=0;i<cntc;i++) 65 { 66 int len=cyc[i].size(); 67 for(int k=0;k<len;k++) 68 { 69 ans[cyc[i][k]]=cyc[i][(k+m)%len]; 70 } 71 } 72 for(int i=0;i<n;i++) 73 { 74 anss[ans[i]]=i; 75 } 76 for(int i=0;i<n;i++) 77 { 78 puts(pk[anss[i]]); 79 } 80 } 81 return 0; 82 }