一.约瑟夫问题
题目:有n个小孩围成一圈,对小孩进行编号1-n,从编号为m的小孩开始从1到k重复报数,报到k数字的小孩出列,问小孩子出列的顺序 以及 最后剩下小孩的编号为多少?(n,m,k从键盘输入)
思路:
先定义两个变量,用reportNum来记录小孩报的数,用outofChild来记录小孩出列的个数,
再定义一个数组 child[n] 用于保存小孩的数据,并将数组元素全部归零,这样我们就可以数组元素来判断小孩是否出列(可以用0代表没有出列,1代表出列),
这时还需要一个变量index,用index变量来记录报数小孩的下标位置,index = (m-1)%n。
具体代码如下:
#include <stdio.h>
int main(){
int n = 0;
printf("请输入小孩个数:");
scanf("%d",&n);
int child[n] ;
int j = 0;
for(;j<n;j++){
child[j] = 0; //0代表没有出列,-1代表出列
}
printf("请输入从编号为多少的小孩开始报数[1-%d]:",n);
int m;
scanf("%d",&m); // index = (m-1)%n
printf("请输入报到数字多少的小孩出列:");
int k = 0;
scanf("%d",&k);
printf("出列顺序:");
int reportNum = 0;//用来记录小孩报的数
int outOfChild = 0;//用来记录小孩出列的个数
int index = (m-1)%n; //用来记录报数小孩的下标位置
while(outOfChild < n-1){
if(child[index] == 0){
++reportNum;
if(reportNum == k){
outOfChild++;
child[index] = 1;
reportNum = 0;
printf("%d ",index+1);
}
}
++index;
if(index>=n){
index = 0;
}
}
printf("\n");
for(i=0;i<n;i++){
if(child[i]==0){
printf("最后剩下的小孩编号为:%d\n",i+1);
break;
}
}
return 0;
}
运行结果如下:
二:斐波那契数列
(1)题目:
1 1 2 3 5 8 13 21 34 55
把前10项结果保存到数组中,并输出
思路:斐波那契数列倒还算较为简单的题目,首先最重要的是我们需要的是找到该数列的规律,经过观察发现,该数列从第三项开始往后,每个数列的项都等于前两项之和,由此我们可以直接定义一个数组arr[10],再通过一个循环来实现该数列。
#include <stdio.h>
int main(){
int arr[10] = {1,1};
int i = 0;
for(i=2;i<10;i++){
arr[i] = arr[i-1] + arr[i-2];
}
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
运行结果如下:
(2)进阶版
写一个函数,求斐波那契数列的第n项
首先,我们可以先用简单点的方法来实现:
#include <stdio.h>
void feibo(long long int a[],int n){
int i = 0;
a[0] = 1;
a[1] = 1;
for(i=2;i<=n;i++){
a[i] = a[i-1] + a[i-2];
}
printf("%lld\n",a[n-1]);
}
int main(){
int n = 0;
printf("请输入需要斐波那契数列的第几项:");
scanf("%d",&n);
long long int a[n];
feibo(a,n);
return 0;
}
运行结果如下:
还有,斐波那契数列还可以通过递归和递推的方法来实现。
不过一定要注意,用递归方法来实现斐波那契数列这种每一次调用都会产生两个新的调用时,调用深度一定不能太深,递归调用次数太深时会造成栈溢出
具体代码如下:
#include <stdio.h>
//递推 从简到难
long long int feibo(int n){
long long int fir = 1;
long long int sec = 1;
long long s = 0;
int i = 3;
for(;i<=n;i++){
s = fir+sec;
sec = fir;
fir = s;
}
return fir;
}
//递归 从难到简
long long int fb(int n){
if(n==1||n==2){
return 1;
}
return fb(n-1)+fb(n-2);//公式
}
int main(){
printf("%lld \n",feibo(100));
printf("%lld \n",fb(40));//递归调用深度不能太深
return 0;
}
实现结果如下:
三:杨辉三角
题目:
输入行数n 打印杨辉三角型的前n行
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
思路:
首先,和斐波那契数列一样,我们首先需要找到该三角的规律所在,
我们先把这三角看成是一个 n*n 的数列 a[n][n],横纵下标分别设为 row 和 col ,当 row==col 或 col ==0 时,a[row][col] == 1 ;当col <= row 时,a[row][col] == a[row-1][col] + a[row-1][col-1] ;而当col > row时,则不需要显示任何东西。
具体实现代码如下:
#include <stdio.h>
int yanghui(int row,int col){
if(col == 0 || row == col){
return 1;
}
return yanghui(row-1,col)+yanghui(row-1,col-1);
}
int printfyanghui(){
printf("请输入一个正整数:");
unsigned int n = 0;
scanf("%d",&n);
for(int row=0;row<n;row++){
for(int col=0;col<=row;col++){
printf("%2d ",yanghui(row,col));
}
printf("\n");
}
}
int main(){
printfyanghui();
return 0;
}
代码实现结果如下:
这次就先这三道题吧,当然这样的题还有很多,这随着C语言的学习越来地越深入,遇到的问题也是越来越多,随着这些问题的一个个解决,你才会发现C语言有时也会是挺有趣的,能够用一些简单的代码,来实现解决一些复杂的问题,这也正是代码的魅力所在。