演算法競賽入門經典(第二版)第二章迴圈結構程式設計例題與提示上
阿新 • • 發佈:2018-11-04
2.1for迴圈
- 儘管for迴圈反覆執行相同的語句,但這些語句每次執行效果往往不同
- 建議儘量縮短變數的定義範圍。例如,在for迴圈的初始化部分定義迴圈變數
- 編寫程式時要特別留意“當前行”的跳轉和變數的改變
- 例題 2-1 aabb
輸出所有形如aabb的4位完全平方數。
-虛擬碼
for(int a=1;a<9;a++)
for(int b=0;b<9;b++)
if(aabb是完全平方數)printf("%d\n",aabb)
int main() { for(int a=1;a<=9;a++) for(int b=0;b<=9;b++) { int n=a*1100+b*11; int m=floor(sqrt(n)+0.5); if(m*m==n)printf("%d\n",n); //一般改成四捨五入,即floor(x+0.5),因為在大量計算後由於誤差整數1變成了0.999999999,floor的結果會是0而不是1 }
//用列舉思路平方根x從而避免開平方的操作
int main()
{ for(int x=1;;x++)
{ int n=x*x;
if(n<1000) continue;
if(n>9999)break;
int hi=n/100;
int lo=n%100;
if(hi/10==hi%10&&lo/10==lo%10)printf("%d\n",n);
}
}
- 不拘一格的使用虛擬碼來思考和描述演算法是一種值得推薦得到做法
- 把虛擬碼改寫成程式碼時,一般先選擇較為容易的任務來完成
- 浮點運算可能會有誤差。在進行浮點數比較時,應考慮到浮點誤差
2.2 while迴圈和do-while迴圈
- 例題2-2 3n+1問題
猜想:對於任意大於1的自然數n,若n為奇數,則將n變為3n+1,否則變為n的一半。經過若
幹次這樣的變換一定會使n變為1.例如,3-10-5-16-8-4-2-1
//有bug版本:乘法溢位了int整數的範圍即-2^31~2^31-1,可以通過Long long解決問題但要把%d改%lld
int main()
{ int n,count=0;
scanf("%d",&n);
while(n>1)
{ if(n%2==1)n=n*3+1;
else n/=2;
count++;
}
printf("%d\n",count);
rerurn 0;
}
- 當需要統計某種事物的個數時可以用一個變數來充當計數器
- 不要忘記測試。一個看上去正確的程式可能隱含錯誤
- 在觀察無法找出錯誤時可以用”輸出中間結果“的方法查錯
- C99並沒有規定Int型別的確切大小但在當前流行的競賽平臺中int都是32位整數
- long long 在linux下輸入輸出格式符為%lld,但windows有時為%164d。為保險起見可用c++
- 例題2-3近似計算
計算∏/4=1-1/3+1/5-1/7+…,直到最後一項小於10^-6
int main()
{ double sum=0;
for(int i=0;;i++)
{ double term=1.0/(i*2+1);
if(i%2==0) sum+=term;
else sum-=term
if(term<le-6)break;
}
printf("%.6f\n",sum);
}