慈母手中线,游子身上衣。
前言
不知不觉暑假已经过去了,更加恐怖的是,我已经开学了几天了,开学这几天在做SYC上面的C语言,一个原因是受人所托,二呢,一个暑假都没有看过写过C了,自己有好多都忘记了。而且做的时候,发现上学期学的C真的很基础,很简单,很多C里面的东西都没有学到,就正好get一些新的知识啦~
编程题是根据字母(A~Z)分类的,后面5道是给学长做的(哇,学姐就不能做了么,抠鼻),但是好吧,我自己觉得前面(A~P)才是属于基础一些的题目,所以写的WP就从P开始分类吧。
题目和代码
说明
这里面的题基本都用了一个相同的点,也是我之前没见过的,就是你没说停下,就可以一直输入。大概是长这个样子 未给定行数的用while(scanf(它的参数)!=EOF)处理
然后那种简单的题目,就不贴思路了~有些题目有很多种方法,就直接写在下面注释了,也是可以用的~
A-ASCII码排序
#include <stdio.h>
int main (void)
{
char s[3],m,x,y,z;
while (scanf("%s",s)!=EOF)
{
x=s[0];
y=s[1];
z=s[2];
if(x>y)
{
m=x;
x=y;
y=m;
}
if(x>z)
{
m=x;
x=z;
z=m;
}
if(y>z)
{
m=y;
y=z;
z=m;
}
printf("%c %c %c\n",x,y,z);
}
return 0;
}
/*{
if(x>z && y>z)
{
printf("%c %c %c\n",z,x,y);
}
else if(x<z && y>z)
{
printf("%c %c %c\n",x,z,y);
}
else if(x<z && y<z)
{
printf("%c %c %c\n",x,y,z);
}
}
fflush(stdin);//清除输入缓冲区*/
/*
char m,x,y,z;
while (scanf("%c%c%c",&x,&y,&z)!=EOF)
{
fflush(stdin);
if(x>y)
{
m=x;
x=y;
y=m;
}
if(x>z)
{
m=x;
x=z;
z=m;
}
if(y>z)
{
m=y;
y=z;
z=m;
}
printf("%c %c %c\n",x,y,z);
*/
B-计算两点间的距离
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (void)
{
double x1,y1,x2,y2;
double length;
while(scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2)!=EOF)
{
length=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
printf("%.2lf\n",length);
}
return 0;
}
C-计算球的体积
#include <stdio.h>
#define PI 3.1415927
int main(void){
double r,v;
while(scanf("%lf",&r)!=EOF)
{
v=((r*r*r)*4*PI)/3;
printf("%.3lf\n",v);
}
return 0;
}
D-求绝对值
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (void)
{
double x;
while (scanf("%lf",&x)!=EOF)
{
printf("%.2lf\n",fabs(x));
}
return 0;
}
E-Digital Roots
思路
这个题一开始没有做,因为可能是懒吧,不想看英语,然后强迫症觉得少了一个题,很不开心,就硬着头皮把他读下来了
题意:把输入的数每个位上的数相加,一直加到只剩一个数为止
eg:39 3+9=12 1+2=3
这个题目有坑哦~因为这题测试数据可能会很长,所以不能一位一位数字来取,又想到用字符串的方式处理。
代码
#include <stdio.h>
#include <string.h>
int main() {
char str[10000];
int sum;
int i;
while (scanf("%s", str) != EOF) {
if(str[0]=='0')
{
break;
}
sum = 10;
while (sum >= 10) {
sum = 0;
for (i = 0; str[i] != 0; i++) {
sum += str[i] - '0';
}
sprintf(str, "%d", sum);
}
printf("%d\n", sum);
}
return 0;
}
新知识
在这里新学会了一个sprintf 的运用
贴一个链接sprintf的运用
#include<stdio.h>
int main(void)
{
char s[40];
sprintf(s,"%s%d%c","test",1,'2'); //存到字符串里面去了
/*第一个参数就是指向要写入的那个字符串的指针,剩下的就和printf()一样了
//可以比较一下,这是向屏幕输入
// printf("%s%d%c","test",1,'2');
printf("%s",s);
return 0;
}
因此上面的代码可以简化成为这样(然而,这个代码我没有扔到题目上,只是本地测试了一下,是可以的)
#include <stdio.h>
#include <string.h>
int main (void)
{
char s[1000];
int sum,i;
while (scanf("%s",s) != EOF)
{
if(strcmp(s,"0") == 0)
{
break;
}
sum =10;
while (sum >= 10)
{
sum =0;
for (i=0;s[i] != '\0';i++)
{
sum+= s[i] - '0';
if(sum > 9)
{
sum=sum%10+sum/10;
}
}
//sprintf(s, "%d", sum);//真的很方便啊!
}
printf("%d\n",sum);
}
return 0;
}
F-求奇数的乘积
#include <stdio.h>
int main(void)
{
int n,num[100],i;
int res;
while (scanf("%d",&n) != EOF)
{
res = 1;
for(i=0;i<n;i++)
{
scanf("%d",&num[i]);
if(num[i]%2!=0)
{
res*=num[i];
}
}
printf("%d\n",res);
}
return 0;
}
G-数值统计
#include <stdio.h>
int main(void)
{
int n,i;
double a[100];
int num1,num2,num3;
while (scanf("%d",&n)!= EOF)
{
num1=0;num2=0;num3=0;
if(n==0)
{
break;
}
for (i=0;i<n;i++)
{
scanf("%lf",&a[i]);
if(a[i] ==0)
{
num2++;
}
else if(a[i] <0 )
{
num1++;
}
else if(a[i]>0)
{
num3++;
}
}
printf("%d %d %d\n",num1,num2,num3);
}
return 0;
}
H-多项式求和
思路
一开始把题目都看错了,以为都是加,还说怎么一直都没有正确答案,后来才看到自己题目都理解错了。既然有加有减,那肯定和(-1)的n次方有关了啊
代码
#include <stdio.h>
int main(void)
{
int m=-1;
int n,i,j;
int num[100];
double sum;
while (scanf("%d",&n) != EOF)
{
for(i=0;i<n;i++)
{
scanf("%d",&num[i]);
sum=0;
m=-1;
for (j=1; j<=num[i]; j++)
{
m = m*(-1);
sum = sum+ m*(1.0/j);
}
printf("%.2lf\n",sum);
}
}
return 0;
}
新知识
这里学了一个关于A的B次方的C语言用法
利用math.h中的pow()函数进行:
函数定义如下:
double pow(double x,double y)
可以实现x的y次幂(返回值)
example:
#include <stdio.h>
#include <math.h>
int main()
{
printf("%f",pow(2,3));
return 0;
}
I-蟠桃记
思路
这个题开始我想用递归做的,后来觉得这样太麻烦了,可以直接倒推回去
(剩下的桃子+1)*2 就是上一天的桃子啊
代码
#include <stdio.h>
int main(void)
{
int n,sum,i;
while (scanf("%d",&n) != EOF)
{
sum=1;
for(i=1;i<n;i++)
{
sum=(sum+1)*2;
}
printf("%d\n",sum);
}
return 0;
}
J-Encoding
题意
就是计算出现相同字母的次数,1的时候不用标注
代码
#include <stdio.h>
#include <string.h>
#include <math.h>
int main(void)
{
int n,i,num;
char str[10000];
int length;
scanf("%d",&n);
while(n--)
{
num=1;
scanf("%s",str);
length=strlen(str);
for(i=0;i < length;i++)
{
if(str[i]==str[i+1])
{
num++;
}
else
{
if(num<=1)
{
printf("%c",str[i]);
num=1;
}
else
{
printf("%d%c",num,str[i]);
num=1;//一定记得为1,不然后面出问题
}
}
}
printf("\n");
}
return 0;
}
K-字符串统计
#include <stdio.h>
#include <string.h>
int main(void)
{
int n,i;
int num;
char s[1000];
scanf("%d",&n);
while (n--)
{
scanf("%s",s);
num=0;
for(i=0;i<strlen(s);i++)
{
if(s[i] >='0' && s[i] <='9')
{
num++;
}
}
printf("%d\n",num);
}
return 0;
}
L-数列有序!
####注意
这个题应该是可以采取折半查找的,做的时候没有想到。实在是不应该。这个题用的是冒泡排序
代码
#include <stdio.h>
int main(void)
{
int n,m,i,j;
int a[100];
int temp;
while (scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)
{
break;
}
else
{
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
a[n]=m;
for(i=0;i<n+1;i++)
{
for (j=0;j<n;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for (i=0;i<n+1;i++)
{
if(i==n)
{
printf("%d",a[i]);
}
else
{
printf("%d ",a[i]);
}
}
printf("\n");
}
}
return 0;
}
M-求平均成绩
#include <stdio.h>
#include <math.h>
int main(void)
{
int n,m,sum,count,i,j,flag;
int a[50][50];
double ave1[50],ave2[50];
while (scanf("%d%d",&n,&m) != EOF)
{
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
//每个人平均成绩
for(i=0;i<n;i++)
{
sum=0;
for(j=0;j<m;j++)
{
sum+=a[i][j];
}
ave1[i]=(sum*1.0)/m;
}
//每门课的平均成绩
for(j=0;j<m;j++)
{
sum=0;
for(i=0;i<n;i++)
{
sum+=a[i][j];
}
ave2[j]=(sum*1.0)/n;
}
//这里比较的时候一定要注意,他是成绩每一科目都要比较,但是是一个人
count=0;
for(i=0;i<n;i++)
{
flag=0;
for(j=0;j<m;j++)
{
if(a[i][j]>=ave2[j])
{
flag++;
}
if(flag==m-1)
{
count++;
}
}
}
/* 第二种方法
count=0;
for(i=0;i<n;i++)
{
flag=1;
for(j=0;j<m;j++)
if(a[i][j]<ave2[j])
{
flag=0;
break;
}
if(flag)
count++;
}*/
for(i=0;i<n;i++)
{
if(i==n-1)
printf("%.2lf\n",ave1[i]);
else
printf("%.2lf ",ave1[i]);
}
for(i=0;i<m;i++)
{
if(i==m-1)
printf("%.2lf\n",ave2[i]);
else
printf("%.2lf ",ave2[i]);
}
printf("%d\n\n",count);
}
return 0;
}
N-查找最大元素
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[100];
int i,j,len;
char max;
while (scanf("%s",s) != EOF)
{
len=strlen(s);
max='a';
for (i=0;i<len;i++)
{
if(s[i]>max)
{
max=s[i];
}
}
for (i=0;i<len;i++)
{
if(s[i]==max)
printf("%c(max)",s[i]);
else
printf("%c",s[i]);
}
printf("\n");
}
return 0;
}
O-Text Reverse
题意
字符串以一个空格为间隔,倒序排列。
Sample Input
3
olleh !dlrow
m'I morf .udh
I ekil .mca
Sample Output
hello world!
I'm from hdu.
I like acm.
思路
将空格提取出来,空格以前的字符串存储起来,再进行倒序。注意输入的换行要读取了,不然会出错
#include <stdio.h>
#include <string.h>
int main(void)
{
int n,i,j,len,k;
char s1[1000];
scanf("%d",&n);
getchar();//换行
while(n--)
{
gets(s1);
len=strlen(s1);
for (i=0,j=0;i<len;i++)
{
if(s1[i]==' ')//要用单引号 而不是双引号
{
for(k=i-1;k>=j;k--)
{
printf("%c",s1[k]);
}
printf(" ");
j=i+1;
}
}
for(k=len-1;k>=j;k--)//最后一个单词的输出
{
printf("%c",s1[k]);
}
printf("\n");
}
return 0;
}
P-人见人爱A^B
####注意
这个题要注意int的溢出问题
如果我们只是采用一直算的话,不能找到一个数据类型来储存这个数,因此,这个办法是不行的。我们知道,要知道一个幂的后三位,只需要对这个数一直%1000即可,比如1230%1000=230;2323456789%1000=789……这样我们这个问题就简单了,只要每次乘以一个数对1000取余即可。
代码
#include<stdio.h>
int main()
{
int a,b,s,i;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a==0&&b==0)
break;
s=a;
for(i=1;i<b;i++)
{
s=(s*a)%1000;
}
printf("%d\n",s);
}
return 0;
}
后记
磨蹭了几天把前面的题写了。后面的题写了几道,发现有些需要数据结构的知识,只能边学边写了。这里只恨自己不会python,因为平台13号就要关闭了,要是可以自己爬下来多练习练习就好了。而且很多这些代码都没有考虑代码的健壮性。就只能勉强说暂且作为复习C用吧。
这些题目也是一些很基础的ACM题目吧,现在平台第一名是一个对ACM很感兴趣的人,和他交流之后,更加提升了我对算法的兴趣,想这学期结合一下数据结构学习一些算法吧。
反思
1.调试进入函数内部问题
2.循环的时候,定义的变量到底是在循环内(循环内,每次循环就要重新被赋值,要想清楚)
3.换行,空格这些字符,要注意清除缓存fflush(stdin);或者getchar();
4.学到的新知识
1)E题型的sprintf的运用
2)H题型想到的关于A的B次方的C语言用法