利用vector的解法
软二的同学们,还记得老师布置的POJ3032那道题吗?当时在学搜索,是练习搜索的。POJ3032 数据范围小 n <= 13。现在 n <= 20000。还用搜索肯定会超时,甚至搜不出来。最后面是我的解法,先给出正解。
利用一个容器维护剩余牌的数目及位置,O(1)时间内确定下一张牌的位置。\
CTRICK - Card Trick
\
The magician shuffles a small pack of cards, holds it face down and performs the following procedure:
- The top card is moved to the bottom of the pack. The new top card is dealt face up onto the table. It is the Ace of Spades.
- Two cards are moved one at a time from the top to the bottom. The next card is dealt face up onto the table. It is the Two of Spades.
- Three cards are moved one at a time…
- This goes on until the nth and last card turns out to be the n of Spades.
This impressive trick works if the magician knows how to arrange the cards beforehand (and knows how to give a false shuffle). Your program has to determine the initial order of the cards for a given number of cards, 1 ≤ n ≤ 20000.
Input
On the first line of the input is a single positive integer, telling the number of test cases to follow. Each case consists of one line containing the integer n.
Output
For each test case, output a line with the correct permutation of the values 1 to n, space separated. The first number showing the top card of the pack, etc…
Example
Input:
2
4
5
Output:
2 1 4 3
3 1 4 5 2
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
using namespace std;
#define M 20005
int n;
int main()
{
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
vector<int>q(n + 2, 0);
vector<int>pos(n + 2, 0);
for (int i = 0; i <= n; i++)
pos[i] = i;//存放位置
int cur = 1, left = n;
for (int i = 1; i <= n; i++) {
cur = (cur + i) % left;
if (cur == 0) cur = left;
int des = pos[cur];
q[des] = i;
pos.erase(pos.begin() + cur);//位置用过后,就将其删去
--left;
}
printf("%d", q[1]);
for (int i = 2; i <= n; i++)
printf(" %d", q[i]);
printf("\n");
q.clear();
pos.clear();
}
return 0;
}
\
\
\
Card Trick 换了几种提交姿势,本地1.4s 限时3s+,TLE\
#include <cstdio>
#include <cstring>
#include <iterator>
#include <iostream>
#include <ctime>
using namespace std;
#define N 20007
int ary[N];
int main()
{
//clock_t start = clock();
ios::sync_with_stdio(false); //节约时间
int n;
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
while(~scanf("%d", &n)) {
//while(cin >> n) {
int cnt = 1, cur = 0, left = n; //cur游标,cnt为要填入的数字
memset(ary, 0, sizeof ary);
while(cnt <= n) {
int k = 0, j = cnt % left; //j用于优化
while(k < j) { //寻找j个空格
// if (ary[cur] == 0)
// k++;
k += (!ary[cur]); // 节约时间
cur = (cur + 1) % n;
}
while(ary[cur] != 0) {//寻找下一个空,填数
cur = (cur + 1) % n;
}
ary[cur] = cnt++;
left--;
}
// printf("%d", ary[0]);
// for (int i = 1; i < n; ++i) {
// printf(" %d", ary[i]);
// }
// puts(""); //4.76 s
copy(ary, ary + n - 1, ostream_iterator<int>(cout, " "));
cout << ary[n - 1] << endl; //实验证明这种流处理快些
//clock_t ends = clock(); //实验室台式机太好,本1.45s
//cout <<"Running Time : "<<(double)(ends - start)/ CLOCKS_PER_SEC << endl;
}
return 0;
}
\
\