PTA-暑期学校-Day6(C语言)

1 A乘以B

给定两个绝对值不超过100的整数A和B,输出A乘以B的值。

要求:

  1. 输入格式
    输入在第一行给出两个整数A和B(-100<=A,B<=100),数字间以空格分隔。
  2. 输出格式
    在一行中输出A乘以B的值。
  3. 输入样例

-8 13

  1. 输出样例

-104

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<string.h>
int main()
{
    int A,B;
    scanf("%d %d",&A,&B);
    int C;
    C=A*B;
    printf("%d",C);
    return 0;
}

2 比较大小

要求将输入的任意3个整数从小到大输出。

要求:

  1. 输入格式
    输入在一行中给出3个整数,其间以空格分隔。
  2. 输出格式
    在一行中将3个整数从小到大输出,其间以“->”相连。
  3. 输入样例

4 2 8

  1. 输出样例

2->4->8

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int x,y,z;
    scanf("%d %d %d",&x,&y,&z);
    if(x>y&&y>z)
        printf("%d->%d->%d",z,y,x);
    if(x>z&&z>y)
        printf("%d->%d->%d",y,z,x);
    if(y>z&&z>x)
        printf("%d->%d->%d",x,z,y);
    if(y>x&&x>z)
        printf("%d->%d->%d",z,x,y);
    if(z>x&&x>y)
        printf("%d->%d->%d",y,x,z);
    if(z>y&&y>x)
        printf("%d->%d->%d",x,y,z);
    if(x==y&&x<z)
        printf("%d->%d->%d",x,y,z);
    if(x==z&&x<y)
        printf("%d->%d->%d",x,z,y);
    if(y==z&&y<x)
        printf("%d->%d->%d",z,y,x);
    if(x==y&&y==z)
        printf("%d->%d->%d",x,y,z);
    return 0;
}

3 求组合数

编写程序,根据公式如下算出从n个不同元素中取出m个元素(m<=n)的组合数。
在这里插入图片描述
建议定义和调用函数fact(n)计算n!,其中n的类型是int,函数类型是double

要求:

  1. 输入格式
    输入在一行中给出两个正整数m和n(m<=n),以空格分隔。
  2. 输出格式
    按照格式“result = 组合数计算结果”输出。题目保证结果在double类型范围内。
  3. 输入样例

2 7

  1. 输出样例

result = 21

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
double fact(int x)
{
    double y=1.0;
    for(int i=2;i<=x;i++)
    {
        y=y*i;
    }
    return y;
}
int main()
{
    int m,n;
    scanf("%d %d",&m,&n);
    double result;
    result=fact(n)/(fact(m)*fact(n-m));
    printf("result = %.0f\n",result);
    return 0;
}

4 求奇数分之一序列前N项和

编写程序,计算序列 1 + 1/3 + 1/5 + … 的前N项之和。

要求:

  1. 输入格式
    输入在一行中给出一个正整数N。
  2. 输出格式
    在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。
  3. 输入样例

23

  1. 输出样例

sum = 2.549541

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int N;
    scanf("%d",&N);
    double S;
    int s=1;
    for(int i=1;s<=N;i=i+2)
    {
        S=S+1.0/i;
        s++;
    }
    printf("sum = %.6lf",S);
    return 0;
}

5 输出闰年

输出21世纪中截止某个年份以来的所有闰年年份。注意:闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。

要求:

  1. 输入格式
    输入在一行中给出21世纪的某个截止年份。
  2. 输出格式
    逐行输出满足条件的所有闰年年份,即每个年份占一行。输入若非21世纪的年份则输出"Invalid year!"。若不存在任何闰年,则输出“None”。
  3. 输入样例1

2048

  1. 输出样例1

2004
2008
2012
2016
2020
2024
2028
2032
2036
2040
2044
2048

  1. 输入样例2

2000

  1. 输出样例2

Invalid year!

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
    int y;
    scanf("%d",&y);
    if(y<=2000||y>2100)
        printf("Invalid year!\n");
    else
    {
        int count=0;
        for(int i=2001;i<=y;i++)
        {
            if(i%4==0&&i%100!=0||i%400==0)
            {
                printf("%d\n",i);
                count++;
            }
        }
        if(count==0)
            printf("None");
    }
    return 0;
}

6 猴子吃桃问题

一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个;第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第N天早上想再吃时,见只剩下一个桃子了。问:第一天共摘了多少个桃子?

要求:

  1. 输入格式
    输入在一行中给出正整数N(1<N≤10)。
  2. 输出格式
    在一行中输出第一天共摘了多少个桃子。
  3. 输入样例

3

  1. 输出样例

10

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int N;
    scanf("%d",&N);
    int sum=1,d=1;
    while(d<N)
    {
        sum=2*(sum+1);
        d++;
    }
    printf("%d",sum);
    return 0;
}

7 最长连续递增子序列

给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。

要求:

  1. 输入格式
    输入第1行给出正整数n(≤105);第2行给出n个整数,其间以空格分隔。
  2. 输出格式
    在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。
  3. 输入样例

15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10

  1. 输出样例

3 4 6 8

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    int n;
    scanf("%d",&n);
    int i,a[100000];
    int left=0,right=0,len=0,mlen=0,l=0;
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n;i++)///令len等于整个序列长度;left最左侧的一数据;right序列最右侧的数据
    {
        len++;
        if(len>mlen)
        {
            mlen=len;
            left=l;
            right=i;
        }
        if(a[i]>=a[i+1])///当右侧数据小或等于左侧数据,序列结束,len归零,l重新计数
        {
            len=0;
            l=i+1;
        }
    }
    for(i=left;i<right;i++)
        printf("%d ",a[i]);
    printf("%d",a[i]);
    return 0;
}

8 求前缀表达式的值

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

要求:

  1. 输入格式
    输入在一行内给出不超过30个字符的前缀表达式,只包含 +-*/ 以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
  2. 输出格式
    输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR
  3. 输入样例

++ 2 * 3 - 7 4 / 8 4

  1. 输出样例

13.0

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
double exp()
{
    char a[10];  //存储第一个非空格字符
    scanf("%s",a);
    if( !a[1])
    {
        //a[1]为空只有一位
        switch( a[0])
        {
        case '+' :
            return exp()+exp();
        case '-' :
            return exp()-exp();
        case '*' :
            return exp()*exp();
        case '/' :
        {
            double fenzi = exp();
            double fenmu = exp();
            if(fenmu !=0) return fenzi/fenmu;
            else
            {
                printf("ERROR");  //分母为0
                exit(0);   //程序结束
            }
        }
        default :
            return atof(a);   //字符串转换为浮点数
        }
    }
    else
    {

        if( a[0]=='-' || a[0]=='+')
        {
            char flag = a[0];  //记录符号
            int i =0 ;
            while(a[i])
            {
                a[i] = a[i+1];
                i++;
            }
            if(flag=='-')
                return 0-atof(a);
            else return atof(a);
        }
        else return atof(a);
    }
}
int main()
{
    printf("%.1f",exp());
    return 0;
}

9 打印学生选课清单

假设全校有最多40000名学生和最多2500门课程。现给出每门课的选课学生名单,要求输出每个前来查询的学生的选课清单。注意:每门课程的选课人数不可超过 200 人。

要求:

  1. 输入格式
    输入的第一行是两个正整数:N(≤40000),为前来查询课表的学生总数;K(≤2500),为总课程数。此后顺序给出课程1到K的选课学生名单。格式为:对每一门课,首先在一行中输出课程编号(简单起见,课程从1到K编号)和选课学生总数(之间用空格分隔),之后在第二行给出学生名单,相邻两个学生名字用1个空格分隔。学生姓名由3个大写英文字母+1位数字组成。选课信息之后,在一行内给出了N个前来查询课表的学生的名字,相邻两个学生名字用1个空格分隔。
  2. 输出格式
    对每位前来查询课表的学生,首先输出其名字,随后在同一行中输出一个正整数C,代表该生所选的课程门数,随后按递增顺序输出C个课程的编号。相邻数据用1个空格分隔,注意行末不能输出多余空格。
  3. 输入样例

10 5
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6

  1. 输出样例

ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int N=26*26*26*10+1;
typedef struct list
{
    int lid;
    struct list* next;
} L;
typedef struct table
{
    L* head;
    L* tail;
    int cnt;
} T;
T* st[26*26*26*10+1];
int ID(char s[])
{
    return (int)((s[3]-'0')+(s[2]-'A')*10+(s[1]-'A')*26*10+(s[0]-'A')*26*26*10);
}
int main()
{
    for(int i=0; i<N; i++)
    {
        T* t=(T*)malloc(sizeof(T));
        t->head=(L*)malloc(sizeof(L));
        t->head->next=NULL;
        t->cnt=0;
        t->tail=t->head;
        st[i]=t;
    }
    int n,k;//查询课表的学生总数,总课程数
    scanf("%d%d",&n,&k);
    for(int i=1; i<=k; i++)
    {
        int cid,stnum;//课程编号,选课学生总数
        scanf("%d%d",&cid,&stnum);
        for(int j=0; j<stnum; j++)
        {
            char sid[5];
            scanf("%s",sid);
            int id=ID(sid);
            L* t=(L*)malloc(sizeof(L));
            t->lid=cid;
            t->next=NULL;
            st[id]->tail->next=t;
            st[id]->tail=st[id]->tail->next;
            (st[id]->cnt)++;
        }
    }

    for(int i=0; i<n; i++)
    {
        char sid[5];
        scanf("%s",sid);
        printf("%s",sid);
        int id=ID(sid);
        printf(" %d",st[id]->cnt);
        L* p=st[id]->head->next;
        //桶排序
        int* ck=(int*)malloc(sizeof(int)*(k+1));
        for(int i=1; i<=k; i++)
        {
            ck[i]=0;
        }
        while(p)
        {
            ck[p->lid]=1;
            p=p->next;
        }

        for(int i=1; i<=k; i++)
        {
            if(ck[i]==1)
            {
                printf(" %d",i);
            }
        }
        free(ck);//释放内存
        printf("\n");
    }
    return 0;
}

10 修理牧场

农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数 Li 个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是 Li 的总和。
但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。
请编写程序帮助农夫计算将木头锯成N块的最少花费。

要求:

  1. 输入格式
    输入首先给出正整数N(≤104 ),表示要将木头锯成N块。第二行给出N个正整数(≤50),表示每段木块的长度。
  2. 输出格式
    输出一个整数,即将木头锯成N块的最少花费
  3. 输入样例

8
4 5 1 2 1 3 1 1

  1. 输出样例

49

代码长度限制 16KB
时间限制 400ms
内存限制 64MB

代码:

#include<stdio.h>
#include<stdlib.h>
// 自定义一个将数组从小到大排序的方法
void sort(int *a,int m){
    int i=0,j=0,t;
    for(i=0;i<m;i++){
        for(j=0;j<i;j++){
            if(a[j]<a[i]){
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
    }
}
int main()
{
    int N,costsum=0,i,index;
    scanf("%d",&N);
    int *a=malloc(sizeof(int)*N);
    for(i=0;i<N;i++)
       scanf("%d",&a[i]);
       // 输入完毕,排列数组
      	sort(a,N);
    	int sum=0;
      for(i=0;i<N-1;i++){
      	// 找出前两个数(即为数组最小的两个数)相加
        sum=a[i]+a[i+1];
        // 花费求和
        costsum=costsum+sum;
        // 比较之前两个最小数的和与数组中各个元素的大小,找到合适的位置,将其放入数组
        // 从第三个数开始,前两个最小数拿出去求和了
        for(index=i+2;index<N;index++)
        {
        	// 前两个数的和大于当前值,继续往后找
            if(sum>a[index])
                a[index-1]=a[index];
            else
            {
            // 不大于就找到位置,结束循环
                a[index-1]=sum;
                break;
            }
        }
        // 比到最后一个数还没找到,就把sum加到最后
        if(index==N)
            a[N-1]=sum;
    }
    printf("%d\n",costsum);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值