1. 程式人生 > >【學習筆記】演算法競賽:chapter 2 迴圈結構程式設計

【學習筆記】演算法競賽:chapter 2 迴圈結構程式設計

對於大部分人來說這部分都不陌生,我也就不再贅述,只寫出一些本書中提到的編寫迴圈結構程式時的需要注意的地方。

1、for迴圈的格式為:for( 初始化;條件;調整 )    迴圈體;

2、儘管for迴圈反覆執行相同的語句,但這些語句每次的執行效果往往不同。

3、編寫程式時,要特別留意“當前行”的跳轉和變數的改變。

4、不拘一格的使用虛擬碼來思考和描述演算法是一種值得推薦的做法。

5、把虛擬碼改成程式碼時,一般先選擇較為容易的任務來完成。

6、浮點運算可能存在誤差。在進行浮點數比較時,應考慮到浮點誤差。

7、while迴圈的格式為“while( 條件 ) 迴圈體 ;  ”

8、當需要統計某件事物的個數時,可以用一個變數來充當計數器。

9、不要忘記測試。一個看上去正確的程式可能隱含錯誤。

尋找錯誤的方法:

(1)利用IDE設定斷點,跟蹤除錯,單步執行

(2)輸出中間結果                            

10、在迴圈體開始處定義的變數,每次執行迴圈體時會重新宣告並初始化。

11、要計算只含有加法、減法和乘法的整數表示式除以正整數n的餘數,可以在每步計算之前對n取餘,結果不變。

12、可以使用<ctime>和clock()函式獲得程式執行時間。常數CLOCK_PER_SEC和作業系統相關;不要直接使用clock()的返回值,而應總是除以CLOCK_PER_SEC之後得到的值為以“秒”為單位。

13、很多程式的執行時間與規模n存在著近似的簡單關係。可以通過計時函式來發現或驗證這一關係。

計時函式:c/c++中的<time.h>中的clock();

14、對於輸入引數不確定個數的情況:

while( scanf ( " %d ", &x ) == 1 )

//當輸入結束時,scanf無法再次讀取x,將返回0

{

  迴圈體;

  }

while( scanf("%d %d", &a , &b) ==2

{

   迴圈體;

}

while( cin>> a>> b 

{

迴圈體;

}

15、變數在未賦值之前的值是不確定的。特別的,它不一定等於0。

16、int型別是32位整數,long long型別是64位整數。

long long 輸出形式:%I64d(gcc) ;%lld (vs2010)

#include <cstdio>
#include <iostream>
using namespace std;
int main(){
    long long s;
    cin>>s;
    <strong><span style="color:#6600cc;">printf("%I64d",s);</span></strong>
	return 0;
}

17、要在C++程式中使用c語言標頭檔案,請去掉拓展名.h,並在最前面加上小寫字母c。例如:<stdio.h> 在c++中應該是:<cstdio>

18、標準輸入流cin比檔案流fin慢很多很多。

7744問題

例:aabb
輸出所有形如aabb的四位完全平方數(前兩位數字相等、後兩位數字相等)。


參考程式碼:

//7744問題
#include<iostream>
#include<cmath>
using namespace std;
int main(){
	int a,b,n;
	double m;
	for( a=1;a<=9;a++){
		for(b=0;b<=9;b++ ){
			n=a*1100+b*11;
			m=sqrt(n);
			//floor(x)函式返回x的整數部分,浮點數的運算可能存在誤差
			//為了減小誤差的影響,改為四捨五入,即floor(x+0.5) 
			if(floor(m+0.5)==m)
			    cout<<n<<endl;
		}
	}
	return 0;
} 


3n+1問題

考慮一下數列的生成辦法.由n開始.   如果   n是偶數除以2.   如果是奇數,   除以3加1.   這樣產生一個新的n,   長此以往,直到n   =   1.   例如   n   =   22:   

22   11   34   17   52   26   13   40   20   10   5   16   8   4   2   1   
歷史證明:0~1000   000無所例外 

輸入n,輸出變換的次數。n小於等於10^9。

樣例輸入:3

樣例輸出:7

參考程式碼:

//3n+1問題
#include<iostream>
using namespace std;
int main(){
	int n,count=0;
	cin>>n;
	while(n>1){
		if(n%2==1)
			n=3*n+1;
		else
			n/=2;
			count++;
	}
	cout<<count<<endl;
	return 0;
} 


階乘之和

輸入n,計算s=1!+2!+....+n!的末6位(不含前導0)

參考程式碼:

#include<iostream>
using namespace std;
int main(){
	int n,sum=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		int temp=1;
		for(int j=1;j<=i;j++){
			temp*=j;
		}
		sum+=temp;
	}
	cout<<sum%100000<<endl;
	return 0;
}

檔案操作:資料統計

#include<cstdio>
#define INF 0xffffff0;
int main(){
	FILE *fin,*fout;
	fin=fopen("data.in","rb");
	fout=fopen("data.out","wb");
	int x;
	int n=0;
	int min=INF;
	int max=-INF;
	int s=0;
	while(fscanf(fin,"%d",&x)==1){
		s+=x;
		if(x<min) min=x;
		if(x>max) max=x;
		n++;
	}
	fprintf(fout, "%d %d %3.1f\n", min, max, (double)s/n);
	fclose(fin);
	fclose(fout);
	return 0;
}