有趣的代码——有故事背景的程序设计3
这篇文章再和大家分享一些有“背景”的程序设计,希望能够让大家学到知识的同时,对编程学习更感兴趣,更能在这条路上坚定地走下去。
目录
1.幻方问题
2.用函数打印九九乘法表
3.鸡兔同笼问题
4.字数统计
5.简单选择排序
1.幻方问题
幻方又称魔方阵,游戏规则是在一一个n*n的矩阵中填入1到n2的数字,使得每一行、每一列、每条对角线的累加和都相等。如下图所示是一个3阶幻方,每一行、每一列每条对角线的累加和都等于15。
解决幻方问题的方法很多,下面介绍一种“左上斜行法”的填数方法,该方法适用于任意奇数阶幻方,具体填数过程如下:
(1)由1开始填数,将1放在第1行的中间位置;
(2)将幻方想象成上下、左右相接,每次往左上角走一一步,会有下列情况:
①左上角超出上边界,则在最下边对应的位置填入下一个数,如图A所示;
②左上角超出左边界,则在最右边对应的位置填入下一个数,如图 B所示;
③按上述方法找到的位置已填数,则在原位置的同一列下一行填入下一个数,如图 C所示:
算法实现如下:
设数组a[n][n]表示幻方,当前填数的位置为(i,j),则其左上方的位置是(i-1,j-1),将被填的数作为循环变量。
1.初始化填数的位置,i=0,j=n/2;
2.在位置(i,j)填入1;
3.数字k从2~n*n重复执行下述操作:
3.1从位置(i,j)往左上角走到位置(i-1,j-1);
3.2如果i超出上边界,则i=n-1;
3.3如果j超出左边界,则j=n-1;
3.4如果位置(i,j)已经填数,则在原位置的同一列下一行填入k;否则,在位置(i,j)填入k
3.5k++;
代码实现如下:
#include<stdio.h>
int main()
{
int arr[100][100]={0},num,i,j,k;//num是咱预处理的幻方阶数
int tempi,tempj;//这里的目的是暂存i,j的值,因为达到边界,i,j的值会发生变化
printf("请输入1-100内的奇数:\n"); //只处理为奇数的方阵
scanf("%d",&num);
i=0;j=num/2;
arr[i][j]=1;//算法中的1,2步骤
for(k=2;k<=num*num;k++)
{
tempi=i;
tempj=j;
if(--i<0)
{ //判断当前位置是否超出上边界?
i=num-1;
}
if(--j<0)
{ //判断当前位置是否超出左边界?
j=num-1;
}
if(arr[i][j]>0)
{//如果该位置已经有数,则在该位置下面添加数字
i=(tempi+1)%num;
j=tempj;
}
arr[i][j]=k;
}
for(i=0;i<num;i++)
{
for(j=0;j<num;j++)
printf("%d\t",arr[i][j]);
printf("\n");
}
return 0;
}
这里arr数组为100*100个元素,主要是在有较大测试范围的同时,不占用太多内存,大家自己测试时可以定义一个宏,然后用宏定义数组,这样方便大家根据需要调整数组大小,而且空间利用率更高。
简单优化一个点,使代码更简洁。
#include<stdio.h>
int main()
{
int arr[100][100]={0},num,i,j,k;//num是咱预处理的幻方阶数
int tempi,tempj;//这里的目的是暂存i,j的值,因为达到边界,i,j的值会发生变化
printf("请输入1-100内的奇数:\n"); //只处理为奇数的方阵
scanf("%d",&num);
i=0;j=num/2;
arr[i][j]=1;//算法中的1,2步骤
for(k=2;k<=num*num;k++)
{
tempi=i;
tempj=j;
i=(i-1+n)%n;//这两步属于是把取模玩明白了,大家可以细品一下
j=(j-1+n)%n;
if(arr[i][j]>0)
{//如果该位置已经有数,则在该位置下面添加数字
i=(tempi+1)%num;
j=tempj;
}
arr[i][j]=k;
}
for(i=0;i<num;i++)
{
for(j=0;j<num;j++)
printf("%d\t",arr[i][j]);
printf("\n");
}
return 0;
}
2.用函数打印九九乘法表
打印九九乘法表,要求用函数实现。
相信大家对于打印九九乘法表已经很熟悉了吧,我们在这里简单和函数结合一下,就满足这个故事背景了。
算法实现如下:
设函数Table99实现打印九九乘法表的功能
1.循环变量i从1到9,打印第i行;
1.1循环变量j从1到i,打印第j列;
1.1.1打印第i行第j列的值i*j;
1.1.2j++;
1.2第i行打印完毕,打印回车符;
1.3i++准备打印下一行;
代码实现如下:
#include<stdio.h>
void Table99(void);
int main()
{
Table99();
return 0;
}
void Table99(void)
{
int i , j ;
for(i = 1 ; i <= 9 ; i++)
{
for(j = 1 ; j <= i ; j++)
printf("%d * %d = %2d ", j , i , i * j);
printf("\n");
}
}
3.鸡兔同笼问题
笼子里共有M只头N只脚,问鸡和兔各有多少只?要求用函数实现。
这种题就是很典型的数学题用编程来解决,而根据我们的数学涵养,我们理应很容易列出二元一次方程组从而解决问题,现在只需要把方程式通过编程用表达式表现出来即可。
当然唯一要注意的是这里是用函数来解决,大家记住结合函数相关知识进行编程。
算法实现如下:
设函数Chicken为解决鸡兔同笼问题的函数。变量chicken表示鸡的个数,rabbit表示兔的个数,变量M表示头的个数,变量N表示脚的个数。
1.chicken从0~M重复执行下述操作:
1.1rabbit = M -chicken;
1.2如果(2*chicken+4*rabbit等于N),则跳出循环;
1.3将chicken++;
2.如果是提前跳出循环,则输出chicken和rabbit的值;
否则输出“无解”;
#include<Stdio.h>
void Chicken(int M , int N)
{
int chicken,rabbit,count;
for(chicken=0;chicken<=M;chicken++)
{
rabbit=M-chicken;
if(2*chicken+4*rabbit==N)
{
printf("鸡有%d只,兔子有%d只",chicken,rabbit);
break;
}
}
if(chicken>M)
{
printf("输入数据不合理,无解!");
}
}
int main()
{
int M,N;
printf("请输入头的个数和脚的个数:");
scanf("%d%d",&M,&N);
Chicken(M,N);
return 0;
}
4.字数统计
从键盘上输入若干行字符,统计出现的字符总数。
这个题本质就像题干一样很简单,我们只需要一直读取字符(并计数),等读到回车符即可结束。
算法实现如下:
设函数count统计每一行文字的字符数,算法如下:
1.ch=读入一个字符;
2.当ch不是回车时,重复执行下述操作;
2.1sum++;
2.2ch=读入下一个字符;
3.返回sum;
代码实现如下:
#include<stdio.h>
int Count(void)
{
int sum=0;
char ch;
printf("请输入一行文字:");
fflush(stdin);
while((ch=getchar())!='\n')
sum++;
return sum;
}
int main()
{
int charcount=0;
charcount=Count();
printf("字符数:%d\n",charcount);
return 0;
}
5.简单选择排序
将N个元素组成的无序序列调整为有序序列。
什么是简单选择排序呢?我们假设待排序元素进行升序排列,简单选择排序的基本思想是:将整个序列分为有序区和无序区,初始化时有序区为空,无序区含有所有元素;在无序区中找到最小的元素,将它与无序区中的第一个元素交换;不断重复上述过程,直到无序区只剩下一个元素。
算法实现如下:
设置函数Sort实现对无序序列arr[N]进行简单选择排序,参数n表示数组元素的个数。
1.循环变量i从0~n-2,重复执行n-1次下述操作:
1.1在序列arr[i]~arr[n-1]中查找最小值arr[min];
1.2交换arr[min]与arr[i];
1.3i++
2.输出arr[N];
代码实现如下:
#include<stdio.h>
#define N 8
void Sort(int arr[],int n)
{
int i,j,min,temp;
for(i=0;i<n-1;i++)
{
min=i;
for(j=i+1;j<n;j++)
if(arr[j]<arr[min]) min=j;
temp=arr[i];arr[i]=arr[min];arr[min]=temp;
}
}
void Print(int arr[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%3d",arr[i]);
printf("\n");
}
int main()
{
int i=0;
int arr[N]={9,5,3,6,7,8,1,2};
printf("排序前的序列时:");
Print(arr,N);
Sort(arr,N);
printf("排序后的序列时:");
Print(arr,N);
return 0;
}