循环与递归的应用
求2+22+222+2222+......+222222(n个2)精确计算
(1.循环算法)
#include<stdio.h>
#include<math.h>
int main()
{
int s=0,sum=0,n,j;
scanf("%d",&n);
for(j=0;j<n;j++)
{
s=s+pow(10,j)*2;
sum=sum+s;
}
printf("%d",sum);
return 0;
}
运行结果:
(2.递归算法)
#include<stdio.h>
int sum(int n)
{
if(n>1)
{
sum(n)=sum(n-1)*10+2;
n--;
}
else sum(n)=2;
}
int main()
{
int n,s;
scanf("%d",&n);
s+=sum(n);
printf("%d",s);
return 0;
}
运行结果:
编写一个算法,其功能是给一维数组输入任意6个整数,假设为5,7,4,8,9,1,然后建立一个具有如图所示的方阵,并打印出来。
5 7 4 8 9 1
1 5 7 4 8 9
9 1 5 7 4 8
8 9 1 5 7 4
4 8 9 1 5 7
7 4 8 9 1 5
#include<stdio.h>
int main()
{
int j,i,m,k,a[6];
for(i=0;i<6;i++)
scanf("%d",&a[i]);
for(i=0;i<6;i++)
printf("%6d",a[i]);
printf("\n");
m=k=5;
for(i=0;i<5;i++)
{
for(j=0;j<6;j++)
{
printf("%6d",a[k++]);
if(k>5)k=0;
}
k=m;k--;m=k;
printf("\n");
}
return 0;
}
趣味矩阵一
编程打印如下的n*n方阵(两种方法)
1 2 3 4 5 6 7
24 25 26 27 28 29 8
23 40 41 42 43 30 9
22 39 48 49 44 31 10
21 38 47 46 45 32 11
20 37 36 35 34 33 12
19 18 17 16 15 14 13
(方法一)
#include<stdio.h>
int main()
{
int i,j,a[100][100],n,k=1;
scanf("%d",&n);
for(i=1;i<=n/2;i++)
{
for(j=i;j<=n-i;j++)//上方
a[i][j]=k++;
for(j=i;j<=n-i;j++)//右侧
a[j][n-i+1]=k++;
for(j=n-i+1;j>=i+1;j--)//下方
a[n-i+1][j]=k++;
for(j=n-i+1;j>=i+1;j--)//左侧
a[j][i]=k++;
}
if(n%2==1)
{i=(n+1)/2;
a[i][i]=n*n;
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
printf("%6d",a[i][j]);
printf("\n");
}
return 0;
}
方法2:
#include<stdio.h>
int main()
{
int t,i,j,k,n,a[10][10],b[2],x,y;
scanf("%d",&n);
b[0]=0;
b[1]=1;
k=n;
t=1;
x=1;
while(x<=n*n){
for(y=1;y<=2*k-1;y++)
{
b[y/(k+1)]=b[y/(k+1)]+t;
a[b[1]][b[0]]=x;
x=x+1;
}
k=k-1;
t=-t;
}
for(i=1;i<=n;i=i+1)
{
printf("\n");
for(j=1;j<=n;j=j+1)
printf("%6d",a[i][j]);
}
return 0;
}
编程打印如下所示的n*n方阵的上三角阵
1 3 6 10 15
2 5 9 14
4 8 13
7 12
11
#include<stdio.h>
int main()
{
int i,j,k=1,a[10][10],n;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
a[i-j+1][j]=k++;
}
for(i=1;i<=n;i++)
{
printf("\n");
for(j=1;j<=n-i+1;j++)
printf("%6d",a[i][j]);
}
return 0;
}
趣味矩阵二
编写程序打印形如图所示的n*n方阵
- 1 1 1 1 1 1 1 1 1 1
- 2 2 2 2 1 1 2 2 2 2
- 2 3 3 2 1 1 2 3 2 1
- 2 3 3 2 1 1 2 3 2 1
- 2 2 2 2 1 1 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1
#include<stdio.h>
int main(){
int x,i,j,k=1,n,a[20][20];
printf("请输入n的值");
scanf("%d",&n);
for(x=1;x<=n/2;x++){
for(i=k;i<n-x+1;i++)//上方
a[x][i]=k;
for(j=i,i=x;i<n-x+1;i++)//右侧
a[i][j]=k;
for( ;i>k;i--)//下方
a[j][i]=k;
for( ;j>k;j--)//左侧
a[j][i]=k;
k++;
}
for(i=1;i<=n;i++){
printf("\n");
for(j=1;j<=n;j++)
printf("%6d",a[i][j]);
}
return 0;
}
优化算法的基本技巧一
P115-12
有52张牌,使他们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面嘲下;第二轮从第3张开始,凡是3的倍数位置上的牌正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌开始,凡是4的倍数位置上的牌按上面相同规则翻转,以此类推,直到翻得牌超过104张为止。统计最后有几张牌正面朝上,以及他们的位置号。
#include<stdio.h>
int main()
{
int a[53],i,j=0,k=2;
for(i=0;i<53;i++)
a[i]=1;
while(j<=104){
for(k=2;k<53;k++){
for(i=k;i<53;i++){
if(i%k==0)
{a[i]=-1*a[i];j++;}
if(j>104)break;
}
if(j>104)break;
}
}
j=0;
for(i=1;i<53;i++)
{
if(a[i]==1)
{
printf("%6d",i);
j++;
}
}
printf("有%d张牌正面朝上",j);
}
P115-(13)
A,B,C,D,E5人为某次竞赛的前五名,他们在名次公布前猜名次。
A说:B得第三名,C得第五名。
B说:D得第二名,E得第四名。
C说:B得第一名,E得第四名。
D说:C得第一名,B得第二名。
E说:D得第二名,A得第三名。
结果每个人都猜对了一半,实际名次是什么呢?
#include<stdio.h>
int main()
{
int a,b,c,d,e;
for(a=1;a<=5;a++)
for(b=1;b<=5;b++)
if(a!=b)
for(c=1;c<=5;c++)
if(c!=a&&c!=b)
for(d=1;d<=5;d++){
if(d!=a&&d!=b&&d!=c)
e=15-a-b-c-d;
if((b==3||c==5)+(d==2||e==4)+(b==1||e==4)+(e==1||b==2)+(d==2||a==3)==5&&(b==3&&c==5)+(d==2&&e==4)+(b==1&&e==4)+(e==1&&b==2)+(d==2&&a==3)==0)
{
printf("a=%d b=%d c=%d d=%d e=%d",a,b,c,d,e);
break;
}
}
return 0;
}
P116-(15)
两个乒乓球队进行比赛,各出3人.甲队为A,B,C三人,乙队为X,Y,Z,三人,已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X、Z比,请编写算法找出3对赛手的名单?
#include<stdio.h>
int main()
{
int a,b,c;
for(a=1;a<=3;a++)
for(b=1;b<=3;b++)
if(a!=b)
{
c=6-a-b;
if(a!=1&&c!=1&&c!=3)
printf("a=%d b=%d c=%d ",a,b,c);
}
return 0;
}
优化算法基本技巧二
P115-(9)有一只经过训练的蜂蜜只能爬向右侧相邻的蜂房,不能反向爬行。如图,试求出蜜蜂从蜂房A爬到蜂房B的可能路线。(0<a<b<100).
3 |
5 |
7 |
4 |
9 |
6 |
8 |
11 |
10 |
13 |
12 |
14 |
#include<stdio.h>
int main()
{
int a,b,i;
int r[100]={1,1};
scanf("%d %d",&a,&b);
for(i=2;i<100;i++)
r[i]=r[i-1]+r[i-2];
printf("路线数位%d",r[b-a]);
return 0;
}
P116-(14)编写算法求满足以下条件的3位整数n:它是完全平方数,其中又有两位数字相同,如144,676等。
#include<stdio.h>
int main()
{
int a,b,c,i;
for(i=10;i<32;i++){
a=i*i/100;
b=i*i/10%10;
c=i*i%10;
if(a==b||a==c||b==c)
printf("%6d",i*i);
}
return 0;
}
P116-(17)完成给“余”猜数的游戏:
心里先想好一个1~100之间的整数x,将它分别除以3,4和7并得到三个余数,把这三个余数输入计算机,计算机能马上猜出这个数。
please think of a number between 1 and 100
your number divided by 3 has a remainder of 1
your number divided by 4 has a remainder of 0
your number divided by 7 has a remainder of 5
let me think a moment...
your number was 40
分析:由算法书中根据数学建模道理推出,d=28a+21b+36c;
其中,a的系数28是4和7的公倍数且被3整除余1
b的系数21是3和7的公倍数,且被4整出余1
c的系数36是3和4的公倍数,且被7整除余1
代码如下:
#include<stdio.h>
int main()
{
int a,b,c,d;
printf("please think of a number between 1 and 100\n");
printf("your number divided by 3 has a remainder of");
scanf("%d",&a);
printf("your number divided by 4 has a remainder of");
scanf("%d",&b);
printf("your number divided by 7 has a remainder of");
scanf("%d",&c);
printf("let me think a moment...");
d=28*a+21*b+36*c;
while(d>84)//3*4*7=84
d=d-84;
printf("your number was%d ",d);
return 0;
}
迭代蛮力法的应用:
P185--(2)猴子吃桃子问题,猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了2个,第二天早上又将剩下的桃子吃了一半,又多吃了两个,以后每天早上都吃了前一天剩下的一半零两个,到第10天早上想在吃时,就只剩下两个了。问第一天猴子摘下来多少个桃子?
#include<stdio.h>
int main()
{
int i,a=2;
for(i=9;i>=1;i--)
a=(a+2)*2;
printf("%d",a);
return 0;
}
P126--(例题5)
一辆吉普车穿越1000千米的沙漠吉普车的总装油量为500加伦,耗油率为1加伦/KM。由于沙漠中没有油库,必须先用这辆车在沙漠中建立临时油库。若吉普车用最少的耗油量穿越沙漠,应在那些地方建立油库,以及各处存储的油量。
#include<stdio.h>
int main()
{
int dis,k,oil;//dis:距终点的距离,1000-dis:距原点的距离 ,oil:储油量,k:往返次数
dis=500;k=1;oil=500;
do{
printf("storepoint%ddistance%doilquantity%d\n",k,1000-dis,oil);
k=k+1;
dis=dis+500/(2*k-1);
oil=500*k;
}
while(dis<1000);
oil=500*(k-1)+(1000-dis)*(2*k-1);
printf("storepoint%ddistance%doilquantity%d",k,0,oil);
return 0;
}
P186--(7)
有一堆棋子,两枚两枚的数,最后余一枚;3枚3枚的数,最后余2枚;5枚5枚的数,最后余4枚;6枚6枚的数,最后余5枚;只有7枚7枚的数,最后正好数完,编程求出这堆棋子最少有多少枚棋子。
#include<stdio.h>
int main()
{
int i,j;
for(i=1; ;i++){
j=7*i;
if(j%2==1&&j%3==2&&j%5==4&&j%6==5)
break;
}
printf("%d",j);
return 0;
}