HDOJ 1005 Number Sequence 非48週期法
阿新 • • 發佈:2019-01-31
Problem DescriptionA number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
InputThe input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
OutputFor each test case, print the value of f(n) on a single line.
Sample Input1 1 31 2 100 0 0
Sample Output25
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
InputThe input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
OutputFor each test case, print the value of f(n) on a single line.
Sample Input1 1 31 2 100 0 0
Sample Output25
網上的版本多數有些問題,最大的問題在於迴圈週期並非48.
這題需要“打草稿”,先求每對a,b出來的數的規律,看一遍輸出估計一下有沒有規律;
然後程式設計找規律,比如重複出現1,1時說明進入了新迴圈;
然後發現有的ab對下不會再出現新的1,1,也就是說第一個元素不參與迴圈週期
——雖然這裡的數對都是(1,0)(2,0)……而題目說不會出現0,但是!7%7=0啦。
此外還有(0,0)對從第三項開始均為0.
整理得到程式如下:
#include<iostream> using namespace std; # define LENT 100 //超過50即可,所謂打草稿的意義 int main() { int a, b,c; int d[7][7][LENT]; //免得輸出時重複算,乾脆儲存個三維陣列 int cycle[7][7]; //儲存每對ab得到數列的迴圈週期 for (a = 0; a < 7; a++) { for (b = 0; b < 7; b++) { cycle[a][b]=0; //用於後續找不符合1,1……的迴圈週期 d[a][b][1]=1; //bug1:忘記做起始資料 d[a][b][2]=1; for (int i = 3; i < LENT; i++) { //尋找符合1,1……的迴圈週期 d[a][b][i] = (a * d[a][b][i-1] + b * d[a][b][i-2]) % 7; if (d[a][b][i]==1){ if(d[a][b][i-1]==1){ cycle[a][b]=i-2; //驗證本項、上一項均為1後,確定週期長為i-2 d[a][b][0]=d[a][b][i-2]; //bug2:當項數恰為週期的倍數時,沒這裡藥丸 break; } } } if (0==cycle[a][b]){ //找不符合1,1……的迴圈週期,用負數標註 for (int i =4; i < 20; i++) { //注意要從第四項開始找 if(d[a][b][i-1]==1)if(d[a][b][i]==d[a][b][3]){ cycle[a][b]=-(i-3); //bug3:算不清週期長度(建議畫個圖) break; } } } //cout<<a <<" "<<b<<": "<<cycle[a][b]<<endl; //可在這加一句輸出看看每對的週期 } } while(cin>>a>>b>>c){ //終於開始輸入輸出!前面部分應該寫成函式呼叫,但我不熟 if (0==c)break; //退出條件 a=a%7; //把ab化成小ab對 b=b%7; if(0>cycle[a][b]){ //判斷出是不符合1,1……的迴圈週期 if(0==c); else { c=c%(-cycle[a][b]); if(c<2)c-=cycle[a][b]; //bug3:畫圖判斷為何有這句 } } else if(0==cycle[a][b]){ //0,0對從第三項開始均為0 if(c>2)c=3; } else c=c%cycle[a][b]; //正常週期的輸出 cout<<d[a][b][c]<<endl; } return 0; }
三維陣列確實看得人很頭疼,書寫也沒有什麼規範,但我好像沒有找到我能理解的又簡潔又正確的答案了……
還有,這裡看著好好的,部落格裡咋全亂了喲。