程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++學習 POJ3032 CARD TRICK

C++學習 POJ3032 CARD TRICK

編輯:C++入門知識

題意:我們要利用n張牌表演一個魔術,魔術的步驟是這樣的:
將開頭一張牌移動到最後,接著拿出這堆牌的第一張,這張牌的數字是1,將這張牌丟棄
將開頭二張牌移動到最後,接著拿出這堆牌的第一張,這張牌的數字是2,將這張牌丟棄
將開頭三張牌移動到最後,接著拿出這堆牌的第一張,這張牌的數字是3,將這張牌丟棄
……
將開頭n張牌移動到最後,接著拿出這堆牌的第一張,這張牌的數字是n
問你,假如要成功地表演這個魔術,我們要將這n張牌排成什麼樣子?請輸出這個排列。
 
分析:一道簡單的模擬題。一開始就有一個直觀想法,枚舉14個數字的全排列,然後依次模擬,判斷哪一個解是符合魔術步驟的,輸出它。但是我算了一下,14個數字的全排列是:87178291200,很明顯,枚舉必定超時。這題其實是要用逆向思維,首先我們必須明確一點,那就是:第一張牌一定在牌堆的第二個位置。其實這就是此題的突破口:每張牌的所在位置都是根據上一個狀態推出的。讓我來舉個例子,對於樣例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。
我使用了deque(雙端隊列)來模擬整個過程,因為雙端隊列支持pop_front和push_front,比較方便。
 
代碼(0ms AC):
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int n,t,ans[20];
void solve(){
    deque Q;
    for(int i=1;i<=n;i++)
      Q.push_back(i);
    int s=1;
    while(!Q.empty()){
       for(int i=1;i<=s;i++){
           int x=Q.front();
           Q.pop_front();
           Q.push_back(x);
       }
       ans[Q.front()]=s++;
       Q.pop_front();
    }
    for(int i=1;i<=n;i++)
     if(i!=n)
      printf("%d ",ans[i]);
     else printf("%d\n",ans[i]);
}
int main()
{
    scanf("%d",&t);
    while(t>=1){
       scanf("%d",&n);
       solve();
    }
    //system("pause");
    return 0;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved