2022.3.17—3.18算法第二章循环结构程序设计学习1

(还少三道题)

目录

一 for循环

例题一

二 while循环和do while 循环

例题二 

例题三​

例题四

三 输入输出框架

例题五

例题六

四 注解与习题

水仙花数

 韩信点兵

倒三角形 


一 for循环

for (初始化;条件;调整)

建议尽量缩短变量的定义范围。例如,在 for 循环的初始化部分定义循环变量

例题一

输出所有形如 aabb 4 位完全平方数(即前两位数字相等,后两位数字也相等)。

思路一:

 

int m = floor(sqrt(n) + 0.5);

 浮点运算可能存在误差,为了减小误差的影响,一般改成四舍五入,即floorx0.5),可以想象成在数轴上把一个单位区间往左移动0.5个单位的距离。floorx)等于1的区间为[12),floorx0.5)等于1的区间为[0.51.5)。

思路二:

二 while循环和do while 循环

while(条件)循环体 。 循环的次数是不确定的,而且 n 也不是 递增 式的循环。

例题二 

对于任意大于1的自然数nn≤10^9。n为奇数,则将n变为3n1,否则变为n的一半;经过若干次这样的变换,一定会使n变为1。例如,3→10→5→16→8→4→2→1。如:输入3,输出7。

#include <stdio.h>
int main()
{
	int n,i;
	scanf("%d",&n);
	while(n!=1)
	{
		if(n%2!=0)//如果n是奇数 
		{ 
			n=3*n+1; 
		}
		else
		{
			n=n/2;
		}
		i++;   //当需要统计某种事物的个数时可以用一个变量来充当计数器。
	}
	printf("%d\n",i);
	return 0;
}

问题:输入987654321,程序卡死。只把int 改成long long 之后,输出都比正确结果多一次。先输出 i 的值,i=1。改正:int n,i=0;把 i 初始化0就对了。为什么i一开始是1?定义变量的时候最好初始化。变量在未赋值之前的值是不确定的,不一定等于0。

在观察无法找出错误时,用“输出中间结果”的方法查错,printf("%d\n",n); 每变换一次就输出一次结果。然后发现第一次输出的是负数。

手册中while的条件是n>1,输入987654321之后输出1;发现第一次输出-1332004332,不满足条件,所以直接输出1。原因:乘法溢出了。

C99并没有规定int类型的确切大小,但在当前流行的竞赛平台中,int都是 32位整数,范围是32位整数,-21474836482147483647

最后:把int 改成long long 

#include<stdio.h>
int main() 
{
	long long  n, count = 0; 
 	scanf("%d", &n); 
 	while(n > 1) 
 	{
  		if(n % 2 == 1) 
  		n = n*3+1; 
  		else 
		n /= 2; 
		count++;
   }
	printf("%d\n", count); 
	return 0; 
}
输入987654321 输出180
do while 循环:先执行一次,再判断条件,条件满足就继续循环。 do{  循环体  }while (条件)

例题三

#include <stdio.h>
int main()
{
	int i=0;
	double sum=0;
	for(i=0;;i++)
	{
		double term = 1.0/(i*2+1);
		if(i%2==0)
		{
			sum+=term;
		}
		else 
		{
			sum-=term;
		}
		if(term<1e-6)   //10的-6次方
		{
			break;;
		}
	}
	printf("%.6f\n",sum);
	return 0;
}

例题四

输入n,计算 S 1 !+ 2 !+ 3 !+ n !的末 6
#include <stdio.h>
int main()
{
	int n,i,sum=1,total=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		sum=sum*i;
		total+=sum;
	}
	printf("%d\n",total%1000000);//输出后6位 
	return 0;
}

问题:乘法溢出。

 25!末尾有6个0,所以从第5项开始,后面的所有项都不会影响和的末6位数字。在最前面加一条语句 ifn25n25。

#include <stdio.h>
int main()
{
	int n,i,sum=1,total=0;
	scanf("%d",&n);
	if(n>25){n=25;}
	for(i=1;i<=n;i++)
	{
		sum=sum*i;
		total+=sum;
	}
	printf("%d\n",total%1000000);//输出后6位 
	return 0;
}
循环结构程序设计中最常见的两个问题:算术运算溢出和程序效率低下,解决方法:输出中间结果和计时函数。

三 输入输出框架

例题五

 输入一些整数,求出它们的最小值、最大值和平均值,保留3位小数,输入保证这些数都是不超过1000的整数。(整数的个数不定)。关于输入不定长数组,第一个可以,第二个不行。

#include <stdio.h>
#define MAX 100
int main()
{
	int arr[MAX]={0};
	int i=0,j=0,t=0,temp=0,min=0,max=0,sum=0;
	double ave=0;  //平均值 
    do
	{
		scanf("%d", &arr[i]);//不定长数组输入 
    	sum+=arr[i];
    	i++;
    }while( getchar() != '\n');
    for(j=0;j<i-1;j++)//冒泡排序,外循环一共i个数,比较i-1次 
    {
    	for(t=0;t<i-j-1;t++)
    	{
    		if(arr[t]>arr[t+1])
    		{
    			temp=arr[t];
    			arr[t]=arr[t+1];
    			arr[t+1]=temp;
			}
		}
	}
	min=arr[0];
	max=arr[i-1];  //最大的数是i-1
    ave=(sum*1.0)/i;
	printf("%d\n",min);
	printf("%d\n",max);
	printf("%.3f\n",ave);
	return 0;
}
在算法竞赛中,选手应严格遵守比赛的文件名规定,包括程序文件名和输入输出文件名。不要弄错大小写,不要拼错文件名,不要使用绝对路径或相对路径。

 C语言文件操作:还没学 = =  以下是手册内容,还没看懂。。(44条消息) C语言文件读写操作(详解)_放码过来呀!!!的博客-CSDN博客_c语言文件读写

 

重定向的方法写起来简单、自然,但是不能同时读写文件和标准输入输出。
//数据统计 重定向版 
#define LOCAL
#include <stdio.h>
#define INF 1000000000
int main()
{
#ifdef LOCAL
	freopen ("data.in","r",stdin);
	freopen ("data.out","w",stdout);
#endif
	int x,n=0,min=INF,max=-INF,s=0;
	while(scanf("%d",&x)==1)
	{
		s+=x;
		if(x<min)min=x;
		if(x>max)max=x;
/*
	printf("x=%d,min=%d,max=%d\n",x,min,max);
*/
	n++;
	}
	printf("%d %d %.3f\n",min,max,(double)s/n);
	return 0;
}
在算法竞赛中,如果不允许使用重定向方式读写数据,应使用 fopen 和fscanf/fprintf进行输入输出。
fopen 的写法稍显繁琐,但是灵活性比较大(例如,可以反复打开并读写文件)
//数据统计 fopen版 
#define LOCAL
#include <stdio.h>
#define INF 1000000000
int main()
{
	FILE *fin,*fout;
	fout=fopen ("data.in","rb");
	fout=fopen ("data.out","wb");
	int x,n=0,min=INF,max=-INF,s=0;
	while(fscanf(fin,"%d",&x)==1)  //把scanf改 成fscanf,第一个参数为fin
	{
		s+=x;
		if(x<min)min=x;
		if(x>max)max=x;
	    n++;
	}
	fprintf(fout,"%d %d %.3f\n",min,max,(double)s/n);//把printf改成fprintf,第一个参数为fout
	fclose(fin);        //最后执行fclose,关闭两个文件。
	fclose(fout);
	return 0;
}

例题六

 输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数),输入保证这些数都是不超过1000的整数,输入每组数据第一行是整数个数n,第二行是n个整数。n0为输入结束标记,程序应当忽略这组数据。相邻两组数据之间应输出一个空行 。

先输入数组元素个数n,再输入数据:使用malloc动态内存分配函数,包含头文#include<malloc.h>

使用方法:

#include <stdio.h>
#include <malloc.h>
int main()
{
	int n,i=0,*list;
	scanf("%d",&n);//输入数组元素个数 
	printf("\n");
	list=(int*)malloc(sizeof(int)*n);//动态开辟内存 
	for(i=0;i<n;i++)
	{
		scanf("%d",&list[i]);
	}
	for(i=0;i<n;i++)
	{
		printf("%d ",list[i]);
	}
	return 0;	
} 

四 注解与习题

水仙花数

1.经常用到的:处理得到一个数x的每一位,先%再/  先/ 再%都行,我感觉第二个比较好记,要得到第几位就除几,然后都对10取余。

个位:x%10

十位:x%100/10

百位:x%1000/100

 2.一个数的几次方#include <math.h>   

a的3次方:pow(a,3)

 韩信点兵

如果 i 能到100,说明10到100之间都没有满足条件的,所以No answer。

#include <stdio.h>
int main()
{
	int a,b,c,i=0,flag=0;
	scanf("%d %d %d",&a,&b,&c);
	for (i=10;i<=100;i++)
	{
		if((i%3==a)&&(i%5==b)&&(i%7==c))
		{
			printf("%d\n",i);
			break;
		}
		else if(i>=100)
		{	
			printf("N0 answer\n");
		}	
	}	
	return 0;
}

(44条消息) break和continue的作用和区别是什么?_陈木舟的博客-CSDN博客_break和continue的作用和区别

倒三角形 

#include <stdio.h>
int main()
{
	int n=0,i=0,j=0,k=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		for(j=0;j<i;j++)
		{
			printf(" ");
		}
		for(j=n-j;j>0;j--)
		{
			printf("* ");
		}
		printf("\n");
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值