算法高效技巧之打表

 

打表是一種典型的用空間換時間的技巧,通常指將全部可能須要用到的結果事先計算出來,這樣後面須要用到時就能夠直接查表得到。打表常見的用法有以下幾種:ios

  一、在程序中一次性計算出全部須要用到的結果,以後的查詢直接取這些結果。git

   這個是最經常使用到的用法,例如在一個須要查詢大量Fibonacci數F(n)的問題中,顯然每次從頭開始計算是很是耗時的,對Q次查詢會產生O(nQ)的時間複雜度;而若是進行預處理,即把全部Fibonacci數預先計算並存在數組中,那麼每次查詢就只需O(1)的時間複雜度,對Q次查詢就值須要O(n+Q)的時間複雜度(其中O(n)是預處理的時間)。算法

  二、在程序B中分一次或屢次計算出全部須要用到的結果,手工把結果寫在程序A的數組中,而後在程序A中就能夠直接使用這些結果。數組

  這種用法通常是當程序的一部分過程小號的時間過多,或是沒有想到好的算法,所以在另外一個程序中使用暴力算法去i出結果,這樣就能直接在源程序中使用這些結果。例如對n皇后問題來講,若是使用的算法不夠好,就容易超時,而能夠在本地用程序計算付出對全部n來講n皇后問題的方案數,而後把算出的結果直接卸載數組中,就能夠根據題目輸入的n來直接輸出結果。函數

  三、對一些感受不會作的題目,先用暴力程序計算小範圍數據的結果,而後找規律,或許就能發現一些「蛛絲馬跡」。spa

  這種用法在數據範圍很是大時候容易用到,由於這樣的題目可能不是用直接能想到的算法來解決的,而須要尋找一些規律才能獲得結果。翻譯

 

 

  例題:PAT乙級1044火星數字code

  

  

火星人是以13進制計數的:

地球人的0被火星人稱爲tret。 
地球人數字1到12的火星文分別爲:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。 
火星人將進位之後的12個高位數字分別稱爲:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。

例如地球人的數字「29」翻譯成火星文就是「hel mar」;而火星文「elo nov」對應地球數字「115」。爲了方便交流,請你編寫程序實現地球和火星數字之間的互譯。

輸入格式:

輸入第一行給出一個正整數N(<100),隨後N行,每行給出一個[0, 169)區間內的數字 —— 或者是地球文,或者是火星文。

輸出格式:

對應輸入的每一行,在一行中輸出翻譯後的另外一種語言的數字。

輸入樣例:

4
29
5
elo nov
tam
輸出樣例:

hel mar
may
115
13

  思路:寫一個初始化函數,把全部的結果保存下來,在main函數中直接找咱們所須要的數字便可。具體代碼以下:blog

  

#include <iostream>
#include <string> 
#include <cstdio>
#include <map>
using namespace std;
string unitDigit[13]={"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"};
string tenDigit[13]={"tret","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"};
string numToStr[170];//數字->火星文
map<string,int> strToNum;//火星文->數字
void init(){
  for(int i=0;i<13;i++){
    numToStr[i]=unitDigit[i];//個位是[0,12],十位爲0
    strToNum[unitDigit[i]]=i;
    numToStr[i*13]=tenDigit[i];//十位是[0,12],個位是0
    strToNum[tenDigit[i]]=i*13; 
  }
  //如下是除個位數和整十位數以外的轉換 
  for(int i=1;i<13;i++){//十位 
    for(int j=1;j<13;j++){//個位 
      string str=tenDigit[i]+" "+unitDigit[j];
      numToStr[i*13+j]=str;
      strToNum[str]=i*13+j;
    }
  }
} 
int main(){
  init();//打表 
  int N;
  scanf("%d%*c",&N);
  for(int i=0;i<N;i++){
    string str;
    getline(cin,str);
    if(str[0]>='0'&&str[0]<='9'){//數字 則轉換爲int數字
      int num=0;
      for(int i=0;i<str.size();i++){
        num=num*10+(str[i]-'0');
      }
      cout<<numToStr[num]<<endl;    
    }else{
      cout<<strToNum[str]<<endl;
    }
  }
  
  return 0;
}
相關文章
相關標籤/搜索