1. 程式人生 > >演算法競賽入門經典 第3章 習題答案

演算法競賽入門經典 第3章 習題答案

習題3-1 分數統計

輸入一些學生的分數,哪個分數出現的次數最多?如果有多個並列,從小到大輸出。

任務1:分數均為不超過100的非負整數

任務2:分數均為不超過100的非負實數,但最多保留兩位小數

#include<stdio.h>
#include<string.h>
#define MAXN 5000
int s[MAXN],m[MAXN][2];
int main()
{
    double x;
    freopen("xt3-1.in","r",stdin)    ;
    int i=0,j=0,temp=0,length,min,max=0,last;
    while(scanf("%lf",&x) == 1)
    {
        temp=x*1000;
        temp=temp%10;
        if (temp>=5) s[i++]=x*100+1;
        else
            s[i++]=x*100;
        printf("%d-%.2lf-%d  ",i-1,x,s[i-1]);
    }
    printf("\n");
    length = i-1;
    for(i=0;i<=length;i++)
    {
        min=s[i];
        for (j=0;j<=i-1;j++)
        {
            if (min<=s[j])
            {
                min=s[j];
                s[j]=s[i];
                s[i]=min;
                for (j=j+1;j<=i;j++)
                {
                    min=s[j];
                    s[j]=s[i];
                    s[i]=min;
                    //printf("%d %d %d\n",min,i ,j);
                }

            }
        }

    }
    j=0;
    for(i=0;i<=length;i++)
    {
        last=i-1;
        if ((i>0)&&(s[last]==s[i]))
        {
            m[j][1]++;
            if (max<m[j][1]) max=m[j][1];
            //printf("+ s[%d]=%d max=%d m[%d][1]=%d m[%d][0]=%d \n",i,s[i],max,j,m[j][1],j,m[j][0]);
        }
        else
            {
                if (i!=0) j++;
                m[j][0]=s[i];
                m[j][1]=1;
              //  printf("n s[%d]=%d max=%d m[%d][1]=%d m[%d][0]=%d \n",i,s[i],max,j,m[j][1],j,m[j][0]);
            }
    }
    //for (i=0;i<=max;i++) printf("m[%d][0]=%d m[%d][1]=%d\n",i,m[i][0],i,m[i][1]);
    for(i=0;i<=length;i++)
    {
        //if (m[i][1]==max) printf("m[%d][0]=%d m[%d][1]=%d max=%d\n",i,m[i][0],i,m[i][1],max) ;
        if (m[i][1]==max) printf("%.2lf\n",m[i][0]/100.0) ;
    }

    return 0;
}


習題3-2 單詞的長度

輸入若干個單詞,輸出它們的平均長度。單詞只包含大寫字母和小寫字母,用一個或多個空格隔開

#include<stdio.h>
#include<string.h>
#define MAXN 5000
char a[MAXN];
int main()
{
    freopen("xt3-2.in","r",stdin);
    int i,j,k,n=0,len=0,sumlen=0,count=0,kongge=1,temp;
    double l;
    fgets(a,sizeof(a),stdin);
    for(i=0;i<=strlen(a)-1;i++)
    {
        //printf("%d\n",a[i]);
        if (((a[i]=='\n')||(a[i]==' ')||(a[i]==EOF))&&(kongge==0))
        {
            sumlen+=len;
            //printf("%d %d\n",len,sumlen);
            len=0;
            kongge=1;
        }
        if ((a[i]!='\n')&&(a[i]!=32)&&(a[i]!=EOF))
        {
            len++;
            if (kongge==1)
            {
                count++;
                kongge=0;
            }
            //printf("長度=%d\n",len);
        }

    }
    sumlen+=len;
    //printf("%d %d\n",sumlen,count);
    temp=(sumlen*100)/count%10;
    if (temp>=5) temp=(sumlen*100)/count+1;
        else temp=(sumlen*100)/count;
    //printf("%d\n",temp);
    printf("%.2lf",temp/100.0);
    return 0;
}


習題3-3  乘積的末3位

輸入若干個整數(可以是正數、負數或者零),輸出它們的乘積的末三位。這些整數中會混入一些由大寫字母組成的字串,你的程式應當忽略它們。提示:試試看,在執行scanf(“%d”)時輸入一個字串會怎樣?

#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAXN 5000
char a[MAXN];
int b[MAXN];
int main()
{
    freopen("xt3-3.in","r",stdin);
    int i,j=0,k,chuli=0,fuhao=1,changdu,kongge=0;
    long plus=1;
    fgets(a,sizeof(a),stdin);
    for (i=0;i<=strlen(a);i++)
    {
        //printf("%d %d %c\n",i,a[i],a[i]);
        chuli=0;
        if (((a[i]==45)||(a[i]==32)||(a[i]==0))||((a[i]>=48)&&(a[i]<=57))) chuli=1;
        if (chuli==1)
        {
            if (a[i]==45) fuhao=-1;
            else
                {

                    if((a[i]==32)||(a[i]==0))
                    {
                        if (kongge==0)
                        {
                            kongge=1;
                            b[j]=b[j]*fuhao;
                            fuhao=1;
                            j++;
                        }
                    }
                    else
                        {
                            kongge=0;
                            b[j]=(a[i]-48)+b[j]*10;
                           // printf("b[%d]=%d\n",j,b[j]);
                        }
                }
        }
        //if(a[i]==0) printf("EOF");
    }
    for (i=0;i<=j-1;i++)
        {
            plus*=b[i];
            //printf("b[%d]=%d plus=%d\n",i,b[i],plus);
        }
    printf("%03d",abs(plus%1000));
    return 0;
}


習題3-4 計算器

編寫程式,讀入一行恰好包含一個加號、減號或乘號的表示式,輸出它的值。這個運算子保證是二元運算子,且兩個數均為不超過100的非負整數。運算數和運算子可以緊挨著,也可以用一個或多個空格、TAB隔開。行首末尾均可以有空格。提示:選擇合適的輸入方法可以將問題簡化。

樣例輸入:1+1

樣例輸出:2

樣例輸入:2-    5

樣例輸出:-3

樣例輸入:0      *1982

樣例輸出:0

#include<stdio.h>
#define MAXN 5000
int main()
{
    int a,b,c;
    char f;
    scanf("%d",&a);
    //printf("1 %d\n",a);
    scanf("%c",&f);
    while((f!='+')&&(f!='-')&&(f!='*')) scanf("%c",&f);
    //printf("2 %c\n",f);
    scanf("%d",&b);
    //printf("3 %d\n",b);
    if (f=='+') c=a+b;
    else
        if(f=='-') c=a-b;
        else
            c=a*b;
    printf("%d",c);
    return 0;
}


習題3-5 選擇

輸入一個n*n的字元矩陣,把它左轉90度後輸出。

#include<stdio.h>
#define MAXN 5000
char a[MAXN][MAXN];
int main()
{
    freopen("xt3-5.in","r",stdin);
    int i=0,j=0,k,n;
    while(scanf("%c",&a[i][j])==1)
    {
        if (a[i][j]!='\n') j++;
            else {i++;j=0;}
        //printf("i=%d j=%d\n",i,j);
    }
    n=i;
    for (i=0;i<=n;i++)
        {
            for (j=n;j>=0;j--)
            printf("%c",a[j][i]);
            if (i!=n)printf("\n");
        }

}


習題3-6 進位制轉換1

輸入基數b(2<=b<=10)和正整數n(十進位制),輸出n的b進製表示。

#include<stdio.h>
int main()
{
    int a[10],b,i=0,j=0,n;
    scanf("%d %d", &b, &n);
    while(n>0)
    {
        a[i]=n%b;
        n=n/b;
        //printf("%d %d \n",n,a[i]);
        i++;
    }
    for(j=i-1;j>=0;j--)
        printf("%d",a[j]);
    return 0;
}


習題3-7 進位制轉換2

輸入基數b(2<=b<=10)和正整數n(b進位制),輸出n的十進位制表示。

#include<stdio.h>
int main()
{
    int i=0,j=0,b,n,temp,wei=1,ji=1,sum=0;
    scanf("%d %d",&b,&n);
    temp = n;
    while (temp>0)
    {
        temp=temp/10;
        if (temp>0) wei*=10;
    }
    printf("wei=%d\n",wei);
    temp=n;
    while(wei>=1)
    {
        i=wei;
        while (i>1)
        {
            ji*=b;
            i=i/10;
            printf("i=%d %d\n",i,ji);
        }
        sum+=(temp/wei)*ji;
        printf("sum=%d\n",sum);
        temp=temp%wei;
        wei/=10;
        ji=1;
    }
    printf("%d",sum);
    return 0;
}


習題3-8 手機鍵盤

輸入一個由小寫字母組成的英文單詞,輸出用手機的預設英文輸入法的敲鍵序列。例如要打出pig這個單詞,需要按1次p,3次i,(稍作停頓後)1次i,記為p1i3i1。

#include<stdio.h>
#define MAXN 5000
int a[MAXN];
int main()
{
    int i=0,j=0,temp=0;
    while(scanf("%c",&a[i])==1)
          {
              for(j=1;j<=8;j++)
              {
                  if ((j==1)&&((temp=a[i]-96)<=3)&&(a[i]!='\n')) {printf("%c%d",a[i],temp);break;}
                  if ((j==2)&&((temp=a[i]-99)<=3)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==3)&&((temp=a[i]-102)<=3)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==4)&&((temp=a[i]-105)<=3)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==5)&&((temp=a[i]-108)<=3)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==6)&&((temp=a[i]-111)<=4)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==7)&&((temp=a[i]-115)<=3)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
                  if ((j==8)&&((temp=a[i]-118)<=4)&&(a[i]!='\n')){printf("%c%d",a[i],temp);break;}
              }
              i++;
          }
    return 0;

}