经典方法(程序片段)

经典方法

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值