11.13集训队招新公开赛题解

写在最前:

        校赛之后感觉我这名次基本上与校集训队无缘了。今天在oj的竞赛列表上看到校队的人发出了一个限时一天的公开赛。本来今天想着好好摆一天烂,但看着题好像也不是特别难,再加上心里有点不甘吧,就花了一个下午加晚上的时间去参与了一下。共六题,前四题中规中矩;第五上了点难度,不过是一种经典的蛇形填数,应该在各大竞赛书里都有收录这种问题;第六题。。目前不会,明年再来看看。


1001:

描述

给定一个k位整数N = dk-1*10k-1 + ... + d1*101 + d0 (0<=di<=9, i=0,...,k-1, dk-1>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定N = 100311,则有2个0,3个1,和1个3。

输入

每个输入包含1个测试用例,即一个不超过1000位的正整数N。

输出

对N中每一种不同的个位数字,以D:M的格式在一行中输出该位数字D及其在N中出现的次数M。要求按D的升序输出。

样例输入

100311

样例输出

0:2
1:3
3:1
题目要求输入不超过1000位,很显然要用字符数组来储存数据了。

在这里我将输入的数一个一个分开,一个一个比对,这样最方便(来自校赛的教训)。字符和整型之间的转换只需要将字符减0即可。

(昨天的校赛第一题,WA和AC这两个字符串与输入进行比较,后来去问了同学才知道把两个字母分开逐个比对,非常方便。当时我还是刻板思维,用了一个strcmp把两个字母放一起比对,一直在runtime error,第一题提交了21遍还是没过。。。泪洒机房)

#include <stdio.h>
int main() {
	char c;
	int a[10] = {0}; 
	int x,i;
	while((c=getchar())!='\n') 
	{
		x=c-'0';
		a[x]+=1;
	}
	for (i = 0; i < 10; ++i) 
	{
	    if (a[i]>0) 
	    printf("%d:%d\n", i, a[i]);
	}
	return 0;
}

1002

描述

编程团体赛的规则为:每个参赛队由若干队员组成;所有队员独立比赛;参赛队的成绩为所有队员的成绩和;成绩最高的队获胜。

现给定所有队员的比赛成绩,请你编写程序找出冠军队。

输入

输入第一行给出一个正整数N(<=10000),即所有参赛队员总数。随后N行,每行给出一位队员的成绩,格式为:“队伍编号-队员编号 成绩”,其中“队伍编号”为1到1000的正整数,“队员编号”为1到10的正整数,“成绩”为0到100的整数。

输出

在一行中输出冠军队的编号和总成绩,其间以一个空格分隔。注意:题目保证冠军队是唯一的。

样例输入

6
3-10 99
11-5 87
102-1 0
102-3 100
11-9 89
3-2 61

样例输出

11 176

队员编号在这道题里没有用。

我自己的这个方法我自己都觉得笨,队伍编号在1000以内那就直接造一个1000大小的数组无脑遍历,做是能做出来,但是在运行时间上和空间占用上并没有优势。

#include<string.h>
#include<stdio.h>
#define maxn 1001
int main()
{
    int n,i,j=0,k,a[maxn],s[maxn],t,p,fs,max;
    memset(a,0,sizeof(a));
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
    scanf("%d-%d",&t,&p);
    scanf("%d",&fs);
    a[t]+=fs;


    }
    max=a[0];
    for(i=1;i<=1000;i++)
    {
        if(a[i]>max)
        {
            max=a[i];
        k=i;
        }

    }
    printf("%d %d",k,max);
    return 0;
    
    

}

(注:排名第一意味着罚时最少,本题共34人,我排名23,没啥优势)

1003 

描述

给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按“PATestPATest....”这样的顺序输出,并忽略其它字符。当然,六种字符的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按PATest的顺序打印,直到所有字符都被输出。

输入

输入在一行中给出一个长度不超过10000的、仅由英文字母构成的非空字符串。

输出

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

样例输入

redlesPayBestPATTopTeePHPereatitAPPT

样例输出

PATestPATestPTetPTePePee

个人感觉这题蛮有意思的。输入就好像是把不同面值的纸币随意摊在桌上给你,你把钱拿过来放在钱包,然后你一张一张整整齐齐的拿出来摆好,拿一张,钱包里对应的纸币就少一张。做法很简单粗暴,就不多解释了。

但还是那句话,这种做法做是能做出来,但是在时间和空间上没什么优势。

#include<stdio.h>
#include<string.h>
#define maxn 10001
int main()
{
    char str[6]={'P','A','T','e','s','t'};
    char c[maxn];
    int i,j,k,p=0,a=0,T=0,e=0,s=0,t=0;
    gets(c);
    for(i=0;i<strlen(c);i++)
    {
        if(c[i]=='P')
        p++;
        else if(c[i]=='A')
        a++;
        else if(c[i]=='T')
        T++;
        else if(c[i]=='e')
        e++;
        else if(c[i]=='s')
        s++;
        else if(c[i]=='t')
        t++;
        

    }
    while(p!=0||a!=0||T!=0||e!=0||s!=0||t!=0)
    {
        if(p!=0)
        {
            printf("P");
            p--;
        }
        if(a!=0)
        {
            printf("A");
            a--;
        }
        if(T!=0)
        {
            printf("T");
            T--;
        }
        if(e!=0)
        {
            printf("e");
            e--;
        }
        if(s!=0)
        {
            printf("s");
            s--;

        }
        if(t!=0)
        {
            printf("t");
            t--;
        }
    }

return 0;

}

(本题共34人,我排名22)

1004

描述

本题要求读入N名学生的成绩,将获得某一给定分数的学生人数输出。

输入

输入在第1行给出不超过105的正整数N,即学生总人数。随后1行给出N名学生的百分制整数成绩,中间以空格分隔。最后1行给出要查询的分数个数K(不超过N的正整数),随后是K个分数,中间以空格分隔。

输出

在一行中按查询顺序给出得分等于指定分数的学生人数,中间以空格分隔,但行末不得有多余空格。

样例输入

10
60 75 90 55 75 99 82 90 75 50
3 75 90 88

样例输出

3 2 0

不用在意分数的值,把分数当成下标,直接输出数组元素即可。

#include<stdio.h>
int main()
{
	int a[101]={ 0 };
	int n=0,i,score=0;
	scanf("%d",&n);
	for (i=0;i<n;i++)
	{
		scanf("%d",&score);
		a[score]++;
	}
	int K;
	int score1;
	scanf("%d",& K);
	for (i=0;i<K;i++)
	{
		scanf("%d",&score1);
		if (i==K-1)
		{
			printf("%d",a[score1]);
		}
		else
		{
			printf("%d ",a[score1]);
		}
	}
}

1005 

描述

本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为m行n列,满足条件:m*n等于N;m>=n;且m-n取所有可能值中的最小值。

输入

输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数。所有数字不超过104,相邻数字以空格分隔。

输出

输出螺旋矩阵。每行n个数字,共m行。相邻数字以1个空格分隔,行末不得有多余空格。

样例输入

12
37 76 20 98 76 42 53 95 60 81 58 93

样例输出

98 95 93
42 37 81
53 20 76
58 60 76

一道经典的蛇形填数题。做这道题之前也是把我许久没打开的算法书翻了出来。

 这题目主要分为三个步骤:找规格、输入排序和打印。

在找规格中,题目明确定义了m大于n,那么将total先开根号,向上取整,让m向上走,通过判断能否整除来寻找n。

#include<stdio.h>
#include<math.h>
#include<string.h>
#define maxn 10001
void sort(int a[],int n)
{
    int i,j,t;
    for(i=1;i<n;i++)
    {
        for(j=0;j<n-1;j++)
        {
            if(a[j]<a[j+1])
            {
                t=a[j+1];
                a[j+1]=a[j];
                a[j]=t;
            }
        }
    }
}
int main()
{
    int total;//输入数据总个数
    scanf("%d",&total);
    int i,a[maxn],b[maxn][100]={0};;//记录数据大小
    for(i=0;i<total;i++)
        scanf("%d",&a[i]);
    int j,t,flag=1;//冒泡排序,从大到小
    sort(a,total);
    int m,n,p,q,k,min=total-1;
    for(m=ceil(sqrt(total));m>=1;m++)
    {
        if(total%m==0)
        {
            n=total/m;
            break;
        }
    }
    p=0,q=0,k=0;
    while(k<total)//顺时针排序
    {
        while(q<n&&!b[p][q])
            b[p][q++]=a[k++];
        p++;
        q--;
        while(p<m&&!b[p][q])
            b[p++][q]=a[k++];
        p--;
        q--;
        while(q>=0&&!b[p][q])
            b[p][q--]=a[k++];
        p--;
        q++;
        while(p>=0&&!b[p][q])
            b[p--][q]=a[k++];
        p++;
        q++;
    }
    for(p=0;p<m;p++)
    {
        for(q=0;q<n;q++)
        {
            if(q==n-1)
                printf("%d\n",b[p][q]);
            else
                printf("%d ",b[p][q]);
        }
    }
    
}

在打印过程中,通过下标的加减,对应了书上讲的“笔”来进行操作

就拿第一个while循环来解释一下:

刚开始的时候我们对整个二维数组b进行了初始化,也就是说,二维数组里面全都是0。

那么,while成立的条件是,q小于n(不能超过列的边界)并且b[p][q]==0(表示即将落笔的位置是空的,未曾落笔)。

欢迎在评论区、私信交流!

               

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

captainfly_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值