天天看點

經典方法(程式片段)

經典方法

1、冒泡法

即使在有相等的數的情況下仍适用。舉例為從小到大排序,從大到小隻需将比較時的大于号換成小于号
           
for(i=0;i<n-1;i++){
	for(j=0;j<n-1-i;j++){//每一趟進行n-1-i次比較
		if(a[j]>a[j+1]){ //相鄰兩個數比較,大的數往後移 
		     t=a[j];
		     a[j]=a[j+1];
		     a[j+1]=t;
	    }	
	}
} 
           

2、由外向内螺旋矩陣

#include<stdio.h> 
main()
{
	int n,m,i,j,x=0,y=0,d=0;//從初始坐标(0,0)開始,d表示初始方向為右(東),x表示行,y表示列 
	int a[10][10]={0};//沒到過的地方全标記為0 
	const int dx[4]={0,1,0,-1};//這裡是代表了四個方向,分别是右,下,左,上(或者說東,南,西,北)
	const int dy[4]={1,0,-1,0};//這裡是順時針旋轉,如果不是順時針,可以根據題目轉換	
	scanf("%d%d",&n,&m) ;
    for(i=1;i<=n*m;i++)
    {
        if((x+dx[d]>=n||y+dy[d]>=m||y+dy[d]<0)||(a[x+dx[d]][y+dy[d]]))//判斷行走的下一個狀态是否碰壁
        {//( 下移時是否碰越下界 || 右移時是否越右界  || 左移時是否越左界) || (若不改變移動方向 下一點是否已經到達過)
             d=(d+1)%4;//碰壁後換移動方向 
        }
        a[x][y]=i;//标記目前到達點 (指派即标記)
        x+=dx[d];
        y+=dy[d];//以目前方向(可能改變也可能未改變)移動一次 
    }
    for(i=0;i<n;i++){
    	for(j=0;j<m;j++){
    		printf("%2d ",a[i][j]);
		}
		printf("\n") ;
	}
	return 0;
}
           

3、逆時針螺旋矩陣

一個nm的左螺旋矩陣是一個從右上角開始逆時針方向旋轉,從nm開始依次填寫數字直到為1的矩陣。

#include<stdio.h> 
main()
{
	int n,m,i,j,x,y,d=0;//從初始坐标(1,1)開始,d表示初始方向為右(東),x表示行,y表示列 
	int a[10][10]={0};//沒到過的地方全标記為0 
	const int dx[4]={0,1,0,-1};//這裡是代表了四個方向,分别是右,下,左,上(或者說東,南,西,北)
	const int dy[4]={-1,0,1,0};//這裡是順時針旋轉,如果不是順時針,可以根據題目轉換	
	scanf("%d%d",&n,&m) ;
	x=0;
	y=m-1;
    for(i=n*m;i>0;i--)
    {
        if((x+dx[d]>=n||y+dy[d]>=m||y+dy[d]<0)||(a[x+dx[d]][y+dy[d]]))//判斷行走的下一個狀态是否碰壁
        {//( 下移時是否碰越下界 || 右移時是否越右界  || 左移時是否越左界) || (若不改變移動方向 下一點是否已經到達過)
             d=(d+1)%4;//碰壁後換移動方向 
        }
        a[x][y]=i;//标記目前到達點 (指派即标記)
        x+=dx[d];
        y+=dy[d];//以目前方向(可能改變也可能未改變)移動一次 
    }
    for(i=0;i<n;i++){
    	for(j=0;j<m;j++){
    		printf("%2d ",a[i][j]);
		}
		printf("\n") ;
	}
	return 0;
}
           

4、josephus問題數組方法

題目描述:

Josephus問題: 一個熱洋芋引發的故事

在食品匮乏的年代,能吃到一個洋芋已經是很幸福的事情,如果這個洋芋還是熱乎的,就更好了。但洋芋隻有一個,有很多人都想吃,怎麼配置設定呢?Josephus想了個辦法,把N個人從1到N編号,圍坐成一個圓圈。然後從1号開始傳遞一個熱洋芋,經過M次傳遞後,拿着熱洋芋的人被清除離座,圍坐的圓圈緊縮,由坐在被清除的人後面那個人拿起熱洋芋繼續進行遊戲,最後剩下的那個人取勝。例如,M=0和N=5時,剩下的是5号。如果M=1和N=5時,被清除的人的順序是2,4,1 ,5,最後剩下的是3号。由于M的值事先并不知道,是以到底誰是人生赢家,能夠吃到這個熱洋芋呢?

輸入格式:

1行,2個整數,中間由逗号隔開。第一個整數表示N個人(0<N<=100),第二個整數表示M(0<=M<=N)。

輸出格式:

1行,N個整數,中間用逗号隔開。這些數字表示離開圓圈的人的順序,用其編号表示。最後-個就是最終剩下的吃熱洋芋的人。

#include<stdio.h>
main()
{
	int n,m,i,j=0,judge;
	int a[101];
	scanf("%d,%d",&n,&m);
	for(i=0;i<n;i++){
		a[i]=i+1;//沒被除掉的數都存在,0則為不存在 
	}
	//重點在于實作圈循環,依靠j%n
	for(i=1;i<n;i++){//傳遞輪次
		for(j=j%n,judge=0;judge!=m;) {//judge判斷傳遞是否夠n次 
			if(a[j%n]!=0){
				judge++;
			}
			j++;
		}
		while(a[j%n]==0){
			j++;
		}//一直找到存在的數為止
		printf("%d,",a[j%n]);
		a[j%n]=0;
	}
	for(i=0;i<n;i++){
		if(a[i]!=0){
			printf("%d",a[i]);//找出最後留下的
		}
	}
	return 0;
}
           

繼續閱讀