传送门:E.Magic Master
John is not only a magic master but also a shuffling master. Famous though he is, he likes interacting with his fans by playing a game with his fantastic shuffling skills. The game shows as follows: He first shows a deck of pokers contains N cards indexed 1,2,…,N and all the cards are the same. He notes that the side contains numbers as the front side and the other side as the back. Later he selects one of his fans to choose a positive integer M that is not greater than 10. After that, he will shuffle the cards purposefully and put it on the desktop. Note that at this moment the front sides of the cards are facing to the desk. Then, the selected fans should perform the following steps until there is no card on the desk.
- Place the card on the top of the piles to John’s hand. If there are already some cards in his hand, put it on the top of them.
- If there remain cards on the desk:
(a) Put a card from the top of the piles to the bottom of it.
(b) Execute the step (a) of M times.
© Go to step 1.
Next, it is time to witness the miracle. John will continually overturn the cards on his hand top to bottom, and we will find that the cards are always in decreasing order. One day, one of John’s fans, Tom, a smart JBer, understands the key to this magic. He turns to you and comments that the key to that magic is the shuffling John did previously. For any number M, he will turn the cards in a specific order after the shuffling. As you are not as smart as Tom, you should find the index of the Kth cards from the top of the piles after the shuffling.
Input
The first line contain a positive integer T (1 ≤ T ≤ 10) – the number of test cases. For each test cases, the first line contain a positive integer N (1 ≤ N ≤ 40000000) , indicating the number of cards. The second line contain a positive integer M (1 ≤ M ≤ 10) – the number the fans selects. The third line contain an integer Q (1 ≤ Q ≤ 100) – indicating that there are Q questions. Next, there are Q lines, each with an integer K (1 ≤ K ≤ N) – representing a query.
Output
For each query, you should output the index of the Kth cards from the top of the piles after the shuffling
样例输入:
1
5
1
2
2
3
样例输出:
5
2
官方题解:
单独用一个数组模拟指针,实现未翻开的牌跳过后面所有翻开的牌,直接指向下一 张未翻开的牌。然后按规则模拟即可。
思路:
我用的双向队列逆向模拟(因为最终的结果是已知的,我们由其逆推最初的状态),利用双向队列的首尾均可操作的性质,时间复杂度应该为 O(N*M) 。
最后顺便整理一下双向队列的一些操作。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<deque>
#include<queue>
#define ll long long
using namespace std;
const int N=5e7+10;
int t,n,m,q,k;
deque<int> qq;
int a[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%d",&m);
qq.push_back(n);
for(int i=n-1;i>=2;i--)
{
qq.push_front(i);
int len=qq.size();
for(int j=0;j<m%len;j++)//防止重复移动,控制时间复杂度
{
int temp=qq.back();
qq.pop_back();
qq.push_front(temp);
}
}
qq.push_front(1);
int id=0;
while(!qq.empty())
{
a[++id]=qq.front();
qq.pop_front();
}
scanf("%d",&q);
while(q--)
{
scanf("%d",&k);
printf("%d\n",a[k]);
}
}
return 0;
}
Elem:数据类型
构造队列:
deque< Elem > c :构造一个空的双向队列
deque< Elem > c1(c2) :复制 deque
数据访问:
c.front() :返回第一个数据
c.back() :返回最后一个数据
c.begin() :返回指向第一个数据的迭代器
c.end() :返回指向最后一个数据的下一个位置的迭代器
c.rbegin() :返回逆向队列的第一个数据
c.rend() :返回指向逆向队列的最后一个数据的下一个位置的迭代器
加入数据:
c.push_back(Elem) :在尾部加入一个数据
c.push_front(Elem) :在头部插入一个数据
c.insert(pos,Elem) :在 pos 位置插入一个 elem ,返回新数据位置
c.insert(pos,n,Elem) :在 pos 位置插入 n 个 elem 数据,无返回值
c.insert(pos,beg,end) :在 pos 位置插入在[beg,end)区间的数据,无返回值
删除数据:
c.pop_back() :删除最后一个数据
c.pop_front() :删除头部数据
c.erase(pos) :删除 pos 位置的数据,返回下一个数据的位置
c.erase(beg,end) :删除[beg,end) 区间的数据,返回下一个数据的位置
其他操作:
c.empty() :判断容器是否为空
c.size() :返回容器中实际数据的个数
c.max_size() :返回容器中最大数据的数量
c.resize(num) :重新指定队列的长度