解释一下样例,因为我觉得这个题意表述的不是很清楚。以第二组样例为例。
牌序为:3 1 4 5 2
第一轮:把 3 放到末尾:1 4 5 2 3,最顶上的牌是1,把1拿走。剩余 4 5 2 3
第二轮:1.把4放到末尾:5 2 3 4
2.把5放到末尾:2 3 4 5
最顶上的牌是2,把 2 拿走,剩余:3 4 5
第三轮:1.把3放到末尾:4 5 3
2.把4放到末尾:5 3 4
3.把5放到末尾:3 4 5
最顶上的牌是3,把 3 拿走,剩余:4 5
第四轮:1.把4放到末尾:5 4
2.把5放到末尾:4 5
3.把4放到末尾:5 4
4.把5放到末尾:4 5
最顶山的牌是4,把 4 拿走,剩余5
第五轮:5次把5放到末尾的操作,把 5 拿走。操作结束。
方法:仍然以第二组样例为例,
一开始是5个空位:-----
1.从第1个位置开始,数 1 个空格: -1---
2.从放1的位置开始,数 2 个空格:-1--2
3.从放2的位置开始,数 3 个空格:31--2 (若后面没有位置,再从第一个位置开始)
4.从放3的位置开始,数 4 个空格:314-2
5.从放5的位置开始,数 5 个空格:31452
即每次超过最后一个位置时,再返回头一个位置。在每次要放的牌 i 之前数 i 个空格就行。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 const int MAXN = 20010; 6 7 int n; 8 int ans[MAXN]; 9 10 int main() 11 { 12 int T; 13 scanf( "%d", &T ); 14 while ( T-- ) 15 { 16 scanf( "%d", &n ); 17 int cur = 1; 18 int pos = 1; 19 memset( ans, -1, sizeof(ans) ); 20 while ( cur <= n ) 21 { 22 int i, cnt; 23 int left = n - ( cur - 1 ); //剩余空格的个数 24 left = cur % left + 1; //一定要取模!!!不然会超时 25 for ( i = pos, cnt = 0; ; ++i ) 26 { 27 if ( i > n ) i = 1; 28 if ( ans[i] == -1 ) ++cnt; 29 if ( cnt == left ) break; 30 } 31 ans[i] = cur; 32 pos = i; 33 ++cur; 34 } 35 36 for ( int i = 1; i <= n; ++i ) 37 { 38 if ( i != 1 ) putchar(' '); 39 printf( "%d", ans[i] ); 40 } 41 puts(""); 42 } 43 return 0; 44 }