SYC基础C语言(A~P)writeup


慈母手中线,游子身上衣。

前言

不知不觉暑假已经过去了,更加恐怖的是,我已经开学了几天了,开学这几天在做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语言用法