洗牌机
题目链接:http://acm.uestc.edu.cn/#/problem/show/1811
Description
有一台洗牌机,它能以同一种环状方式洗牌,但我们不知道这种方式,还有\(13\)张牌\(A,2,3,4,⋯,10,J,Q,K\)(为方便读入,\(A→1,J,Q,K→11,12,13\))。如\(1→2→8→12→4→3→7→6→13→11→5→10→9\)表示在洗一次后,原来的第一张到了现在第二张,原来的第二张到了现在第八张,⋯⋯,第九张到了现在的第1张。某天,这台洗牌机出了点毛病,运行一次只能连续洗牌两次,我们知道牌的初始顺序\(S_0\)和洗牌两次后顺序\(S_2\),求洗牌一次后的顺序\(S_1\)。
Input
第一行13个数表示初始顺序\(S_0\)
第二行13个数表示洗牌两次后顺序\(S_2\)
Output
输出13个数表示洗牌一次后顺序\(S_1\)(请不要在最后一个数后面输出空格 否则可能得到Presentation Error的结果)
Sample Input and Output
Sample Input | Sample Output |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 <br > 10 9 12 8 13 3 4 1 5 11 6 2 7 | 9 1 4 12 11 7 3 2 10 5 13 8 6 |
Hint
\(1→2→8→12→4→3→7→6→13→11→5→10→9\)即为样例的洗牌方式
题意
一次洗牌操作:按照\(1-13\)组成的排列,第\(i\)个数表示目前放置在第\(i-1\)个数位置的牌洗牌后会放置在第\(i\)个位置
题解
\(\gcd(13,2)=1\)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 14;
int Ori[MAXN];
int New[MAXN];
int Hash[MAXN];
int Tran[MAXN];
int Ans[MAXN];
int main()
{
for(int i=1;i<MAXN;++i) cin>>Ori[i];
for(int i=1;i<MAXN;++i) cin>>New[i];
for(int i=1;i<MAXN;++i) Hash[Ori[i]]=i;
for(int i=1;i<MAXN;++i) New[i]=Hash[New[i]];
for(int i=1;i<MAXN;++i) Hash[New[i]]=i;
for(int i=1,p=3,t=1;i<MAXN;++i,p=(p+1)%13+1,t=Hash[t]) Tran[p]=Hash[t];
for(int i=1;i<MAXN;++i) Hash[Tran[i]]=i;
for(int i=1;i<MAXN;++i) Ans[i]=Ori[Tran[(Hash[i]+11)%13+1]];
for(int i=1;i<MAXN;++i) cout<<Ans[i]<<(i==MAXN-1?'\n':' ');
return 0;
}
版权所有:scidylanpno
原文链接:http://www.cnblogs.com/scidylanpno/p/7978031.html