题意
首先告诉你一个洗牌条件
第一次洗牌是把第一张牌放到牌堆底,然后亮出现在牌堆顶的牌是1,然后把1拿走。
第二次洗牌把前两张牌依次放到牌底,亮出现在牌堆顶的牌是2,然后把2拿走。
…
如果某次牌堆可移动的牌少于移动次数,那么就按照第一次移动的样子操作n次,亮出此时牌堆顶的牌,拿走。
按照这种顺序假洗牌,使得最后亮出牌的顺序是1 2 3 …这样的序列。现在问给定你牌的数量,那么如何排列初始牌堆的顺序能达到这样的效果。
思路
看了其它博客,感觉是真的厉害,通常按照逆规则来推这个原序列太麻烦了,但是可以先把一个排好的序列先入队,然后按照上面的规则(不是逆规则)来操作,存数只要下标和数字换换就可以了。(本题不能有行尾多余空格需要注意,我当时ac这题是手推的13种情况 )。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
queue<int> q;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
q.push(i);
}
int k=1;
int v[20]={0};
while(q.size())
{
for(int i=1;i<=k;i++)
{
int t=q.front();
q.pop();
q.push(t);
}
int c=q.front();
q.pop();
v[c]=k;
k++;
}
for(int i=1;i<=n;i++)
{
if(i==n) printf("%d",v[i]);
else printf("%d ",v[i]);
}
puts("");
}
return 0;
}