申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2011年10月25日 星期二

NOIP2007普及組 hanoi雙塔問題

【問題描述】
給定A、B、C三根足夠長的細柱,在A柱上放有2n箇中間有孔的圓盤,共有n個不同的尺
寸,每個尺寸都有兩個相同的圓盤,注意這兩個圓盤足不加區分的(下圖爲n=3的情形)。現要將
這些圓盤移到C柱上,在移動過程中可放在B柱上暫存。要求:
(1)每次只能移動一個圓盤;
(2)A、B、C三根細柱上的圓盤都要保持上小下大的順序;
任務:設An爲2n個圓盤完成上述任務所需的最少移動次數,對於輸入的n,輸出An。

【輸入】
輸入文件hanoi.in爲一個正整數n,表示在A柱上放有2n個圓盤。

【輸出】
輸出文件hanoi.out僅一行,包含一個正整數,爲完成上述任務所需的最少移動次數An。

【輸入輸出樣例1】
hanoi.in
1
hanoi.out
2

【輸入輸出樣例2】
hanoi.in
2
hanoi.out
6

【限制】
對於50%的數據,1<=n<=25
對於100%的數據,l<=n<=200

【提示】
設法建立An與An-1的遞推關係式。

【分析】
設F(x)表示移動2x個圓盤的最小步數。
很容易推出F(x)=2*X^2-2
或者這樣寫:F(x)=F(x-1)*2 最後的F(n)再減2即可,這樣寫可以把高精度乘法換成高精度加法。

【滿分代碼】
//hanoi雙塔問題
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
using namespace std;

char result[1000]; 
void Highj(char a[],char b[]) 
{ 
    int x[1000],y[1000]; 
    int i,l,la,lb; 
    char temp[1000]; 
    for (i=0;i<999;i++){x[i]=0;y[i]=0;} //初始化 
    la=strlen(a); 
    lb=strlen(b); 
     
    //把char型數組 按正倒序  變成整型數組 
    if (la<=lb) 
    { 
        for (i=la-1;i>=0;i--) 
            y[i]=a[la-1-i]-'0'; 
        for (i=lb-1;i>=0;i--) 
            x[i]=b[lb-1-i]-'0'; 
        l=la; 
    } 
    else  
    { 
        for (i=la-1;i>=0;i--) 
            x[i]=a[la-1-i]-'0'; 
        for (i=lb-1;i>=0;i--) 
            y[i]=b[lb-1-i]-'0';     
        l=lb;         
    } 
     
    //執行加法運算 
    for (i=0;i<l;i++) 
    { 
        x[i]=x[i]+y[i]; 
        if (x[i]>=10)  
        { 
            x[i]-=10; 
            x[i+1]+=1; 
        } 
    } 
     
    //再把整型數組按照倒序轉換成char型數組 
    for (i=999;i>=0;i--) 
        temp[999-i]=x[i]+'0'; 
     
    //從不是0的一位開始輸出結果 
    for (i=0;i<=999;i++) 
    { 
        if (temp[i]>'0') 
        { 
            for(int j=i;j<=999;j++) 
                result[j-i]=temp[j]; 
            return; 
        } 
    } 
    //如果沒有一位大於0 
    result[0]='0'; 
    return; 
}  

int main()
{
 freopen("hanoi.in","r",stdin);
 freopen("hanoi.out","w",stdout);
 long long num=1;
 int n;
 cin>>n;
 if (n<90)
 {
  for (int i=1;i<=n;i++)
   num=num*2;
  num=num*2-2;
  cout<<num<<endl;
  return 0;
 }
 if (n>=90)
 {
  char two[1];
  two[0]='2';
  memset(result,'\0',sizeof(result));
  result[0]='1';
  for (int i=1;i<=n+1;i++) 
  {
   Highj(result,result);
  }
  int len=strlen(result);
  if (result[len-1]-'0'>=2)
   result[len-1]=result[len-1]-2;
  else 
  {
   result[len-1]=result[len-1]-2+10;
   result[len-1]=result[len-2]-2;
  }
  cout<<result<<endl;
 }
 return 0;
}


沒有留言:

張貼留言