算法-蓝桥杯习题(2-2)

来源:互联网 发布:2017知豆电动汽车价格 编辑:程序博客网 时间:2024/05/15 03:27

蓝桥杯习题

蓝桥杯练习系统习题加答案,总共分为6部分,90%习题使用C语言解答,部分使用C++或者Java。大部分习题为搜索参考或者别人提供所得,不足之处在所难免,恳请批评指正(预计200多题,习题仅供学习交流)

目录

入门训练(详见 算法-蓝桥杯习题(1-1))Go

基础练习(详见 算法-蓝桥杯习题(2-1))Go

基础练习(详见 算法-蓝桥杯习题(2-2))Go

算法训练(详见 算法-蓝桥杯习题(3-1))Go

算法训练(详见 算法-蓝桥杯习题(3-2))Go

算法训练(详见 算法-蓝桥杯习题(3-3))Go

算法训练(详见 算法-蓝桥杯习题(3-4))Go

算法训练(详见 算法-蓝桥杯习题(3-5))Go

算法训练(详见 算法-蓝桥杯习题(3-6))Go

算法提高(详见 算法-蓝桥杯习题(4-1))Go

历届试题(详见 算法-蓝桥杯习题(5-1))Go

历届试题(详见 算法-蓝桥杯习题(5-2))Go


蓝桥杯练习系统评测数据

链接: http://pan.baidu.com/s/1mhophTQ
密码: m2pa


基础训练(PartB-17题)




/*基础练习 时间转换问题描述  给定一个以秒为单位的时间t,要求用“<H>:<M>:<S>”的格式来表示这个时间。<H>表示时间,<M>表示分钟,而<S>表示秒,它们都是整数且没有前导的“0”。例如,若t=0,则应输出是“0:0:0”;若t=3661,则输出“1:1:1”。输入格式  输入只有一行,是一个整数t(0<=t<=86399)。输出格式  输出只有一行,是以“<H>:<M>:<S>”的格式所表示的时间,不包括引号。样例输入0样例输出0:0:0样例输入5436样例输出1:30:36*/#include<stdio.h>  int main(){  int a,b,c,d;  scanf("%d",&a);  b=(int)(a/3600);  c=(int)(a%3600)/60;  d=(int)((a%3600)%60);  printf("%d:%d:%d",b,c,d);  return 0;  }

/*基础练习 字符串对比问题描述  给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一:  1:两个字符串长度不等。比如 Beijing 和 Hebei  2:两个字符串不仅长度相等,而且相应位置上的字符完全一致(区分大小写),比如 Beijing 和 Beijing  3:两个字符串长度相等,相应位置上的字符仅在不区分大小写的前提下才能达到完全一致(也就是说,它并不满足情况2)。比如 beijing 和 BEIjing  4:两个字符串长度相等,但是即使是不区分大小写也不能使这两个字符串一致。比如 Beijing 和 Nanjing  编程判断输入的两个字符串之间的关系属于这四类中的哪一类,给出所属的类的编号。输入格式  包括两行,每行都是一个字符串输出格式  仅有一个数字,表明这两个字符串的关系编号样例输入BEIjingbeiJing样例输出3*/#include<stdio.h>#include<string.h>int main(){    char a[10],b[10],i,n,l=2;    gets(a);gets(b);    n=strlen(a);    if(strlen(b)!=n)l=1;    else    {    for(i=0;i<n;i++)    if(a[i]==b[i]||a[i]==b[i]+32||a[i]+32==b[i])        if(a[i]!=b[i])l=3;        else ;else {l=4;break;}    }printf("%d",l);return 0;}

/*基础练习 分解质因数问题描述  求出区间[a,b]中所有整数的质因数分解。输入格式  输入两个整数a,b。输出格式  每行输出一个数的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是从小到大的)(具体可看样例)样例输入3 10样例输出3=34=2*25=56=2*37=78=2*2*29=3*310=2*5提示  先筛出所有素数,然后再分解。数据规模和约定  2<=a<=b<=10000*/#include<stdio.h>#include<math.h>int main(){    long int b,i,k,m,n,w = 0;    scanf("%ld%ld",&m,&n);    for(i = m;i<=n;i++)    {        printf("%ld=",i);        b = i;k = 2;        while(k<=sqrt(i))        {            if(b%k==0)            {                b = b/k;                if(b>1)                {                    printf("%ld*",k);continue;                }                   if(b==1) printf("%ld\n",k);            }            k++;        }        if(b>1&&b<i) printf("%ld\n",b);        if(b==i)        {            printf("%d\n",i);w++;        }         }    return 0;}

/*基础练习 矩阵乘法问题描述  给定一个N阶矩阵A,输出A的M次幂(M是非负整数)  例如:  A =  1 2  3 4  A的2次幂  7 10  15 22输入格式  第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数  接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值输出格式  输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格隔开样例输入2 21 23 4样例输出7 1015 22*/#include <stdio.h>#include <string.h>#define N 100int A[N][N],t[N][N],r[N][N];int main(){    int n,m,i,j,k;    scanf("%d%d",&n,&m);    for(i=0;i<n;i++)        for(j=0;j<n;j++)            scanf("%d",&A[i][j]);    for(i=0;i<n;i++)          r[i][i]=1;//单位矩阵,如同数的乘法中的1    while(m--)    {        memset(t,0,sizeof(t));        for(i=0;i<n;i++)            for(j=0;j<n;j++)                for(k=0;k<n;k++)                    t[i][j]+=r[i][k]*A[k][j];        for(i=0;i<n;i++)            for(j=0;j<n;j++)                 r[i][j]=t[i][j];    }    for(i=0;i<n;i++)    {        for(j=0;j<n-1;j++)            printf("%d ",r[i][j]);            printf("%d\n",r[i][j]);        }    return 0;}

/*基础练习 矩形面积交问题描述  平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。输入格式  输入仅包含两行,每行描述一个矩形。  在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。输出格式  输出仅包含一个实数,为交的面积,保留到小数后两位。样例输入1 1 3 32 2 4 4样例输出1.00*/#include <stdio.h>#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))int main(){    double x1,y1,x2,y2;//矩形1     double x3,y3,x4,y4;//矩形2        double m1,n1;//交集左上角坐标     double m2,n2;//交集右下角坐标     scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);    scanf("%lf%lf%lf%lf",&x3,&y3,&x4,&y4);    m1=max(min(x1,x2),min(x3,x4));    n1=max(min(y1,y2),min(y3,y4));    m2=min(max(x1,x2),max(x3,x4));    n2=min(max(y1,y2),max(y3,y4));    if(m2>m1&&n2>n1)          printf("%.2f\n",(m2-m1)*(n2-n1));        else         printf("0.00\n");    return 0;}

/*基础练习 完美的代价问题描述  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。  交换的定义是:交换两个相邻的字符  例如mamad  第一次交换 ad : mamda  第二次交换 md : madma  第三次交换 ma : madam (回文!完美!)输入格式  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)  第二行是一个字符串,长度为N.只包含小写字母输出格式  如果可能,输出最少的交换次数。  否则输出Impossible样例输入5mamad样例输出3*/#include<stdio.h>  int changes(char s[],char x,int n); char x='0'; int main(void) {    int n,i,k=0,b[26]={0},j;    char y,s[8000]={0};    scanf("%d",&n);    getchar();    for(i=0;i<n;i++)    scanf("%c",&s[i]);    for(i=0;i<n;i++)   {        j=s[i]-'a';        b[j]++;    }    for(j=0;j<26;j++)   {        if(b[j]%2!=0)       {            k++;            x=j+'a';                 }    }    if(k>=2)    printf("Impossible\n");    else    printf("%d\n",changes(s,x,n));    return 0; }  int changes(char s[],char x,int n) {     int i,change=0,j,k;     for(i=0;i<n/2;i++)    {        if(s[i]==x)       {          for(j=i;j<n-i-1;j++)          if(s[n-i-1]==s[j])          break;          change+=j-i;          for(k=j;k>i;k--)          s[k]=s[k-1];          s[i]=s[n-i-1];        }       else        {        for(j=n-i-1;j>=i;j--)        if(s[i]==s[j])        break;        change+=n-i-1-j;        for(k=j;k<n-i-1;k++)        s[k]=s[k+1];        s[n-i-1]=s[i];        }    }      return change; }

/*基础练习 数的读法问题描述  Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。  比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。  所以,他迫切地需要一个系统,然后当他输入12 3456 7009时,会给出相应的念法:  十二亿三千四百五十六万七千零九  用汉语拼音表示为  shi er yi san qian si bai wu shi liu wan qi qian ling jiu  这样他只需要照着念就可以了。  你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。  注意必须严格按照规范,比如说“10010”读作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”读作“shi wan”而不是“yi shi wan”,“2000”读作“er qian”而不是“liang qian”。输入格式  有一个数字串,数值大小不超过2,000,000,000。输出格式  是一个由小写英文字母,逗号和空格组成的字符串,表示该数的英文读法。样例输入1234567009样例输出shi er yi san qian si bai wu shi liu wan qi qian ling jiu*/#include<stdio.h>#include<string.h>int main(){    char a[100];int i,j,k,l;    char b[20][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};    char c[20][10]={"","","shi","bai","qian","wan","shi","bai","qian","yi","shi"};    gets(a);    l=strlen(a);    for(i=0;i<l;i++){        j=a[i]-48;        if(j==0){if(i<l-1)if(a[i+1]!=48)printf("%s ",b[j]);}        else         if((l-i==2||l-i==6||l-i==10)&&j==1)printf("%s ",c[l-i]);        else if(a[i-1]==48&&j==1)printf("%s ",c[l-i]);        else printf("%s %s ",b[j],c[l-i]);    }    printf("\n");    return 0;}

/*基础练习 Sine之舞问题描述  最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功。所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力。  不妨设  An=sin(1–sin(2+sin(3–sin(4+...sin(n))...)  Sn=(...(A1+n)A2+n-1)A3+...+2)An+1  FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题。输入格式  仅有一个数:N<201。输出格式  请输出相应的表达式Sn,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。样例输入3样例输出((sin(1)+3)sin(1–sin(2))+2)sin(1–sin(2+sin(3)))+1*/#include <stdio.h>void printA(int n, int k){    if (n == k)        printf("sin(%d)", n);    else    {        printf("sin(%d", n);        printf(n % 2 == 0 ? "+" : "-");        printA(n + 1, k);        printf(")");    }}void printS(int n, int k){    if (n == 1)    {        printA(1, n);        printf("+%d", k - n);    }    else    {        printf("(");        printS(n - 1, k);        printf(")");        printA(1, n);        printf("+%d", k - n);    }}int main(){    int N;    scanf("%d", &N);    printS(N, N + 1);    printf("\n");    return 0;}

/*基础练习 FJ的字符串问题描述  FJ在沙盘上写了这样一些字符串:  A1 = “A”  A2 = “ABA”  A3 = “ABACABA”  A4 = “ABACABADABACABA”  … …  你能找出其中的规律并写所有的数列AN吗?输入格式  仅有一个数:N ≤ 26。输出格式  请输出相应的字符串AN,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。样例输入3样例输出ABACABA*/#include<stdio.h>void f(int a){    if(a==0)printf("%c",'A');    else     {        f(a-1);        printf("%c",a+'A');        f(a-1);    }}int main(){    int a;scanf("%d",&a);f(a-1);printf("\n");    return 0;}

/*基础练习 芯片测试问题描述  有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多。  每个芯片都能用来测试其他芯片。用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏。而用坏芯片测试其他芯片时,会随机给出好或是坏的测试结果(即此结果与被测试芯片实际的好坏无关)。  给出所有芯片的测试结果,问哪些芯片是好芯片。输入格式  输入数据第一行为一个整数n,表示芯片个数。  第二行到第n+1行为n*n的一张表,每行n个数据。表中的每个数据为0或1,在这n行中的第i行第j列(1≤i, j≤n)的数据表示用第i块芯片测试第j块芯片时得到的测试结果,1表示好,0表示坏,i=j时一律为1(并不表示该芯片对本身的测试结果。芯片不能对本身进行测试)。输出格式  按从小到大的顺序输出所有好芯片的编号样例输入31 0 10 1 01 0 1样例输出1 3*/#include<stdio.h>#include<string.h>int main(){    int a[50][50];int i,j,n,s;scanf("%d",&n);     for(j=0;j<n;j++)for(i=0;i<n;i++)scanf("%d",&a[i][j]);    for(j=0;j<n;j++){s=0;for(i=0;i<n;i++)s=s+a[j][i];if(s>n/2.0)printf("%d ",j+1);}    return 0;}

/*基础练习 龟兔赛跑预测问题描述  话说这个世界上有各种各样的兔子和乌龟,但是研究发现,所有的兔子和乌龟都有一个共同的特点——喜欢赛跑。于是世界上各个角落都不断在发生着乌龟和兔子的比赛,小华对此很感兴趣,于是决定研究不同兔子和乌龟的赛跑。他发现,兔子虽然跑比乌龟快,但它们有众所周知的毛病——骄傲且懒惰,于是在与乌龟的比赛中,一旦任一秒结束后兔子发现自己领先t米或以上,它们就会停下来休息s秒。对于不同的兔子,t,s的数值是不同的,但是所有的乌龟却是一致——它们不到终点决不停止。  然而有些比赛相当漫长,全程观看会耗费大量时间,而小华发现只要在每场比赛开始后记录下兔子和乌龟的数据——兔子的速度v1(表示每秒兔子能跑v1米),乌龟的速度v2,以及兔子对应的t,s值,以及赛道的长度l——就能预测出比赛的结果。但是小华很懒,不想通过手工计算推测出比赛的结果,于是他找到了你——清华大学计算机系的高才生——请求帮助,请你写一个程序,对于输入的一场比赛的数据v1,v2,t,s,l,预测该场比赛的结果。输入格式  输入只有一行,包含用空格隔开的五个正整数v1,v2,t,s,l,其中(v1,v2<=100;t<=300;s<=10;l<=10000且为v1,v2的公倍数)输出格式  输出包含两行,第一行输出比赛结果——一个大写字母“T”或“R”或“D”,分别表示乌龟获胜,兔子获胜,或者两者同时到达终点。  第二行输出一个正整数,表示获胜者(或者双方同时)到达终点所耗费的时间(秒数)。样例输入10 5 5 2 20样例输出D4样例输入10 5 5 1 20样例输出R3样例输入10 5 5 3 20样例输出T4 */#include<stdio.h>int main(){    int v1,v2,t,s,l,s1=0,s2=0,i=0;    scanf("%d %d %d %d %d",&v1,&v2,&t,&s,&l);    while(s1<l&&s2<l)    {        s1+=v1;        s2+=v2;        i++;        if(s1==l||s2==l)break;        if(s1-s2>=t)s1-=v1*s;    }    if(s1>s2)      printf("R\n");    else if(s2>s1) printf("T\n");    else           printf("D\n");    printf("%d",i);    return 0;}

/*基础练习 回形取数  问题描述  回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。输入格式  输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。输出格式  输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。样例输入3 31 2 34 5 67 8 9样例输出1 4 7 8 9 6 3 2 5样例输入3 21 23 45 6样例输出1 3 5 6 4 2*/#include <stdio.h>#include <string.h>#define MAX_N 200int m,n;int a[MAX_N][MAX_N],b[MAX_N][MAX_N];int s=0;void solve(int i,int j){    if(i<m && i>=0 && j<n && j>=0 && b[i][j] == 0)    {        printf("%d ",a[i][j]);        b[i][j] = 1;        }    else    {        s++;        return ;    }    if(s%4 == 0)    solve(i+1,j);    if(s%4 == 1)    solve(i,j+1);    if(s%4 == 2)    solve(i-1,j);    if(s%4 == 3)    solve(i,j-1);    if(s%4 == 0)    solve(i+1,j);    if(s%4 == 1)    solve(i,j+1);    if(s%4 == 2)    solve(i-1,j);    if(s%4 == 3)    solve(i,j-1);    return ;}int main(){    memset(b,0,sizeof(b));    scanf("%d%d",&m,&n);    int i,j;    for(i=0; i<m; i++)        for(j=0; j<n; j++)            scanf("%d",&a[i][j]);    solve(0,0);    puts("");    return 0;}

/*基础练习 报时助手问题描述  给定当前的时间,请用英文的读法将它读出来。  时间用时h和分m表示,在英文的读法中,读一个时间的方法是:  如果m为0,则将时读出来,然后加上“o'clock”,如3:00读作“three o'clock”。  如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five thirty”。  时和分的读法使用的是英文数字的读法,其中0~20读作:  0:zero, 1: one, 2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight, 9:nine, 10:ten, 11:eleven, 12:twelve, 13:thirteen, 14:fourteen, 15:fifteen, 16:sixteen, 17:seventeen, 18:eighteen, 19:nineteen, 20:twenty。  30读作thirty,40读作forty,50读作fifty。  对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty one”。  按上面的规则21:54读作“twenty one fifty four”,9:07读作“nine seven”,0:15读作“zero fifteen”。输入格式  输入包含两个非负整数h和m,表示时间的时和分。非零的数字前没有前导0。h小于24,m小于60。输出格式  输出时间时刻的英文。样例输入0 15样例输出zero fifteen*/#include <stdio.h>void printTime(int n){switch(n){case 0: printf("zero"); break;case 1: printf("one") ; break;case 2: printf("two"); break;case 3: printf("three"); break;case 4: printf("four"); break;case 5: printf("five"); break;case 6: printf("six"); break;case 7: printf("seven"); break;case 8: printf("eight"); break;case 9: printf("nine"); break;case 10: printf("ten"); break;case 11: printf("eleven"); break;case 12: printf("twelve"); break;case 13: printf("thirteen"); break;case 14: printf("fourteen"); break;case 15: printf("fifteen"); break;case 16: printf("sixteen"); break;case 17: printf("seventeen"); break;case 18: printf("eighteen"); break;case 19: printf("nineteen"); break;case 20: printf("twenty"); break;default:if(n<40)printf("thirty");else if(n<50)printf("forty");else if(n<60)printf("fifty");break;}return ;}main(){int h,m;scanf("%d%d",&h,&m);//输出小时 if(h>20){printTime(20);printf(" ");printTime(h%10);printf(" ");}else{printTime(h);printf(" ");}//输出分钟if(m){if(m>20){printTime(m/10*10);printf(" ");printTime(m%10);}else{printTime(m);}}else{printf("o'clock");}printf("\n");return 0;} 

/*基础练习 2n皇后问题问题描述  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。输入格式  输入的第一行为一个整数n,表示棋盘的大小。  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。输出格式  输出一个整数,表示总共有多少种放法。样例输入41 1 1 11 1 1 11 1 1 11 1 1 1样例输出2样例输入41 0 1 11 1 1 11 1 1 11 1 1 1样例输出0*/#include<stdio.h>int sum=0;int p(int n,int x,int y,int m[][8],int s){    int i,j;    for(i=x-1;i>=0;i--)    {        if(m[i][y]==s)return 0;    }    for(i=x-1,j=y-1;i>=0&&j>=0;i--,j--)    {        if(m[i][j]==s)return 0;    }    for(i=x-1,j=y+1;i>=0&&j<n;i--,j++)    {        if(m[i][j]==s)return 0;    }    return 1;}int h(int n,int x,int m[][8],int s){    int i;    if(x==n)    {        if(s==2)h(n,0,m,3);        else sum++;        return 0;    }    for(i=0;i<n;i++)    {        if(m[x][i]!=1)continue;        if(p(n,x,i,m,s))m[x][i]=s;        else continue;        h(n,x+1,m,s);        m[x][i]=1;    }    return 0;}int main(){    int n,m[8][8],i,j;        scanf("%d",&n);    for(i=0;i<n;i++)    {        for(j=0;j<n;j++)        {            scanf("%d",&m[i][j]);        }    }    h(n,0,m,2);    printf("%d",sum);    return 0;}

/*基础练习 Huffuman树  问题描述  Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。  给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下:  1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为pa + pb。  2. 重复步骤1,直到{pi}中只剩下一个数。  在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。  本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。  例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:  1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。  2. 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。  3. 找到{8, 9, 10}中最小的两个数,分别是8和9,从{pi}中删除它们并将和17加入,得到{10, 17},费用为17。  4. 找到{10, 17}中最小的两个数,分别是10和17,从{pi}中删除它们并将和27加入,得到{27},费用为27。  5. 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。输入格式  输入的第一行包含一个正整数n(n<=100)。  接下来是n个正整数,表示p0, p1, …, pn-1,每个数不超过1000。输出格式  输出用这些数构造Huffman树的总费用。样例输入5 3 8 2 9样例输出*/#include <stdio.h>typedef struct{    int a[100];    int len;}huf;int sum=0;int del(huf* in,int t){    int i,j;    for(i=0;i<in->len && in->a[i]!=t;i++);    for(;i<in->len-1;i++)        in->a[i]=in->a[i+1];    in->len--;    return 1;}int add(huf* in,int t){    in->a[in->len]=t;    in->len++;}int find_two_mins(huf* in){    int i,j,t;    int mina,minb;    for(i=0;i<in->len-1;i++)        for(j=i+1;j<in->len;j++)            if(in->a[i]>in->a[j])            {                t=in->a[i];                in->a[i]=in->a[j];                in->a[j]=t;            }    mina=in->a[0];    minb=in->a[1];    del(in,mina);    del(in,minb);    add(in,mina+minb);    return mina+minb;}int main(){    huf in;    int i,j,n;    scanf("%d",&n);    in.len=n;    for(i=0;i<n;i++)        scanf("%d",&in.a[i]);    while(1)    {        if(in.len==2)        {            sum=sum+in.a[0]+in.a[1];            break;        }        sum+=find_two_mins(&in);    }    printf("%d",sum);    return 0;}

/*基础练习 高精度加法问题描述  输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。算法描述  由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。  定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。  计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。  最后将C输出即可。输入格式  输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。输出格式  输出一行,表示a + b的值。样例输入201001222010012212345678902010012220100122样例输出20100122203011233454668012*/#include <stdio.h>#include <string.h>#define MaxSize 100+5//逆序输出数组,不输出前导0 void printArray(int P[]){    int i=MaxSize-1;        while(!P[i])    {        i--;    }        while(i>=0)    {        printf("%d",P[i]);        i--;    }        printf("\n");        return ;}//高数相加 void getResult(char a[],char b[],int c[],int a_lenth,int b_lenth){    int next=0,i=0;         while(a_lenth&&b_lenth)    {        c[i++]=((a[--a_lenth]-'0')+(b[--b_lenth]-'0')+next)%10;        next=((a[a_lenth]-'0')+(b[b_lenth]-'0')+next)/10;    }        if(a_lenth==b_lenth)    {        c[i++]=next;    }        while(a_lenth)    {        c[i++]=(a[--a_lenth]-'0'+next)%10;        next=(a[a_lenth]-'0'+next)/10;    }        return ;}main(){    char A[MaxSize],B[MaxSize];    int C[MaxSize];        memset(C,0,sizeof(C));        gets(A);    gets(B);        if(strlen(A)>=strlen(B))    getResult(A,B,C,strlen(A),strlen(B));    else    getResult(B,A,C,strlen(B),strlen(A));        printArray(C);        return 0;}/*#include<stdio.h>#include<string.h>#include<stdlib.h>void f(char a[],char b[]){    int w=200,i,j,la,lb;    la=strlen(a);lb=strlen(b);    char c[200];    for(i=la;i<w;i++)a[i]=48;    for(i=lb;i<w;i++)b[i]=48;    a[w-1]=0;b[w-1]=0;    for(i=0;i<la;i++)c[i]=a[i];    for(i=0;i<w-1-la;i++)a[i]=48;j=0;    for(i=w-1-la;i<w-1;i++){a[i]=c[j];j++;}    for(i=0;i<lb;i++)c[i]=b[i];    for(i=0;i<w-1-lb;i++)b[i]=48;j=0;    for(i=w-1-lb;i<w-1;i++){b[i]=c[j];j++;}    for(i=w;i>=0;i--)    {        j=a[i]+b[i]-96;        if(j>9)a[i-1]=a[i-1]+j/10;        c[i]=j%10+48;    }    c[w-1]=0;    for(i=0;i<w;i++)if(c[i]!='0')break;    for(;i<w-1;i++)printf("%c",c[i]);printf("\n");}int main(){    char a[200],b[200];gets(a);gets(b);    f(a,b);return 0;}*/

/*基础练习 阶乘计算问题描述  输入一个正整数n,输出n!的值。  其中n!=1*2*3*…*n。算法描述  n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。  首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。输入格式  输入包含一个正整数n,n<=1000。输出格式  输出n!的准确值。样例输入10样例输出3628800*/#include <stdio.h>#include <string.h>#define MaxSize 3000+5void resultProduct(int P[],int num){    int i,tp=0,st=0;        for(i=0;i<MaxSize;i++)    {        st=tp;        tp=(P[i]*num+st)/10;        P[i]=(P[i]*num+st)%10;    }    return ;}void printArray(int P[]){    int i=MaxSize-1;        while(!P[i])    {        i--;    }        while(i>=0)    {        printf("%d",P[i]);        i--;    }        printf("\n");        return ;}main(){    int A[MaxSize],n;    int i;        //数组清零且个位初始化为1     memset(A,0,MaxSize*sizeof(int));     A[0]=1;    scanf("%d",&n);    //用i依次乘以数组A     for(i=2;i<=n;i++)    {        resultProduct(A,i);    }        printArray(A);    printf("\n");        return 0;}/*#include <stdio.h>#define N 10000int main(){    int a[N]={1};    int k=0,l=1,n;    int i,j;    scanf("%d",&n);    for(i=1;i<=n;i++)    {        for(j=0;j<l;j++)        {            a[j]=a[j]*i+k;            k=a[j]/10000;            a[j]=a[j]%10000;        }        if(k)        {            a[j]=k;            l++;            k=0;        }    }    printf("%d",a[l-1]);    for(i=l-2;i>=0;i--)        printf("%04d",a[i]);    printf("\n");    return 0;}*/

GoToNextPart

6 0
原创粉丝点击