Card Trick(模拟)

http://poj.org/problem?id=3032

View Code
 1 #include<iostream>
 2 #include<queue>
 3 using namespace std ;
 4 int main()
 5 {
 6     int a[14] ;
 7     int n, t ;
 8     cin>>t;
 9     queue<int>q ;
10     while(t--)
11     {
12         cin>>n ;
13         q.push(n) ;
14         for(int i=n-1; i>=1; i--)
15         {
16             q.push(i) ;
17             for(int j=1; j<=i; j++)
18             {
19                 int x = q.front() ;
20                 q.pop() ;
21                 q.push(x) ;
22             }
23         }
24         for(int i=n-1; i>=0; i--)
25         {
26             a[i] = q.front() ;
27             q.pop() ;
28         }
29         for(int i=0; i<n-1; i++)
30         cout<<a[i]<<" " ;
31         cout<<a[n-1]<<endl ;
32     }
33     return 0 ;
34 }

还可以这样写(0MS) :

View Code
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std ;
 4 int main()
 5 {
 6 
 7     int t;
 8     int n;
 9     int a[14], x;
10     queue<int>q;
11     cin>>t;
12     while(t--)
13     {
14 
15         cin>>n;
16         for(int i=1; i<=n; i++)
17         q.push(i);
18         for(int i=1; i<=n; i++)
19         {
20             for(int j=1; j<=i; j++)
21 
22             {
23                 x=q.front();
24                 q.pop();
25                 q.push(x);
26             }
27             x=q.front();
28             q.pop();
29             a[x]=i;
30         }
31         for(int i=1; i<=n; i++)
32         cout<<a[i]<<" ";
33         cout<<endl;
34     }
35     return 0;
36 }

这题其实是要用逆向思维,首先我们必须明确一点,那就是:第一张牌一定在牌堆的第二个位置。其实这就是此题的突破口:每张牌的所在位置都是根据上一个状态推出的。让我来举个例子,对于样例n=4,模拟的过程就是:

设第一张牌的数字是x1,第二张牌为x2,第三张牌为x3,第四张牌为x4

当前牌堆序列为:x1  x2  x3  x4

将第一张牌移到最后,原序列为: x2 x3 x4 x1,也就是说x2一定是1

删除x2,继续模拟,将前两张牌移动到最后,原序列为:x1 x3 x4,也就是说x1一定是2

以此类推,我们可以还原出整个序列:2 1 4 3。

 

posted @ 2013-03-24 23:16  yelan@yelan  阅读(169)  评论(0编辑  收藏  举报