題目:給定答案序列和使用者猜的序列,統計有多少數字對應正確(a),有多少數字在兩個序列都出現過但位置不對。輸入包括多組資料。每組輸入第一行為序列長度n,第二行是答案序列,接下來是若干猜測序列。猜測序列為0時改組資料結束。n=0時輸入結束。
樣例輸入:41 3 5 5
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
101 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0
樣例輸出:game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
game 2:
(2,4)
(3,2)
(5,0)
(7,0)
我的思路:這裡貼一段錯誤的**;思路看起來是對的,但是實現和debug過程過於麻煩,遠遠不及書上的思路。不必細究。
#includeint main()
b[105];
int n,i,j,t=0,m=0,a[105],k=0;
while(scanf("%d",&n)!=eof && n!=0)
for(i=1;i<=n;i++)//comparing a[i] and b[j].a
}*/b[j].b=1;
break;
}if(a[i]==b[j].a && i!=j && b[j].b==0)} }
printf("game %d: (%d,%d)\n",k,t,m);
t=0;
m=0;
for(i=1;i<=n;i++)
b[i].b=0;}}
return 0;
}//6 5 5 3
//1 2 2 5 5 5 6 6 6 7
這大概是我至今最失敗的幾次程式設計之一了,我定義乙個結構體陣列b,b[i].a
儲存使用者輸入的數,b[i].b
儲存這個數的狀態,如果它被呼叫則置1,如果被錯誤呼叫(即本來是與答案序列正確對應的,但被程式視作不對應從而使m++)置0,同時t++,m--。讀者大概也能夠猜出我的想法:用迴圈巢狀迴圈來尋找位置相同和不相同的數從而獲取a和b的個數。
在經過幾個小時的不斷重複的過程中,我發現耗費在這上面的時間過多,而每一次嘗試都無功而返。
不禁讓我反思自己的問題,在我之前的程式設計中,解決問題的演算法經常出現一些嚴重的漏洞,使我不得不去重新思考這個方法的框架,耗費的時間以小時計。別人十幾分鐘就可以解決的問題我會花上兩三個小時。重新思索其他的解題方法也許是乙個不錯的解決方法,但是我能不能找到它,並且效率是否會高,這還需我自己用時間來檢驗。回到此題,可能是最簡單的演算法:直接統計a,為了計算b,對每個數字(0-9),統計二者出現的次數c1,c2,那麼min(c1,c2)就是該數字對b的貢獻。最後要減去a的部分。**(大體部分):#includeint main()
for(i=1;i<=n;i++)
for(i=1;i<=9;i++)//遍歷1-9
if(c1>c2)m+=c2;
else m+=c1;//m+=min(c1,c2)
c1=0;
c2=0;
}printf("game:(%d,%d)",t,m-t);//計算錯位:m-t
return 0;
}
2016/3/9
《演算法競賽入門經典》習題及反思
題目 給定答案序列和使用者猜的序列,統計有多少數字對應正確 a 有多少數字在兩個序列都出現過但位置不對。輸入包括多組資料。每組輸入第一行為序列長度n,第二行是答案序列,接下來是若干猜測序列。猜測序列為0時改組資料結束。n 0時輸入結束。樣例輸入 41 3 5 5 4 3 3 5 6 5 5 1 6 ...
演算法競賽入門經典 習題2答案
輸入乙個不超過10 9的正整數,輸出他的位數,例如12735的位數是5.請不要使用任何數學函式,只用四則運算和迴圈語句實現 include include define uint unsigned int using namespace std int main cout i endl return...
演算法競賽入門經典習題2 6
用1,2,3,9組成3個三位數abc,def和ghi,每個數字恰好使用一次,要 求abc def ghi 1 2 3。按照 abc def ghi 的格式輸出所有解,每行乙個解 思路 如果首先要保證每個數字都用一次,那麼這個題就會變得很麻煩,所以就先讓abc,def,ghi產生倍數關係然後對 這三個...