(还少三道题)
目录
一 for循环
for (初始化;条件;调整)
例题一
思路一:
int m = floor(sqrt(n) + 0.5);
浮点运算可能存在误差,为了减小误差的影响,一般改成四舍五入,即floor(x+0.5),可以想象成在数轴上把一个单位区间往左移动0.5个单位的距离。floor(x)等于1的区间为[1,2),而floor(x+0.5)等于1的区间为[0.5,1.5)。
思路二:
二 while循环和do while 循环
例题二
对于任意大于1的自然数n,n≤10^9。若n为奇数,则将n变为3n+1,否则变为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位整数,-2147483648~2147483647。
最后:把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
例题三
#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;
}
例题四
#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位数字。在最前面加一条语句 if(n>25)n=25。
#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版
#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个整数。n=0为输入结束标记,程序应当忽略这组数据。相邻两组数据之间应输出一个空行 。
先输入数组元素个数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;
}