新生第二次考核题解

358 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

1:小明被集训队里的大佬嘲讽:“就你还想打ACM?来给你道水题看你能不能做出来。”

小明很气,想请你帮帮他,题目是这样的:

给定一个长度为n的整数数组a_1,a_2,...,a_n,每次操作你可以选择任意两个不同的下标i,j,如果满足那么。你可以进行无数次操作(或不执行),请求出进行操作后可以得到的最小的数组元素之和。

备注:


题解:找规律

代码:

    for(int i=2;i<=n;i++)
    {
        long long t;
        cin>>t;
        g=__gcd(t,g);
    }

2:在去编程学校的路上,李莎面临着她的第一个考验——一个巨大的楼梯!

台阶的编号都是整数,从1开始。李莎在走过了编号为的台阶,并记录下这些编号中偶数的个数a和奇数的个数b

李莎有点笨,可能在数个数的时候记错了某些值。于是她告诉你ab,问是否能找到一个台阶编号区间,满足偶数的个数为a、奇数的个数为b

备注:

LR的范围不做限制,可以相等。

题解: 规律,特判,数据有点问题,在此道歉

代码:

    if(abs(a-b) >= 2 || (a == 0 && b == 0)) puts("NO");

    else puts("YES");

3:瑶瑶姐姐最近准备比赛,但是她每次都不能很好的把控时间,所以瑶瑶姐姐想买一块手表了,现在有这样一块手表:在一条直线上共有n个数字面板,每个面板可以显示09之间的任何数字。最初,所有面板都显示0 。
每秒钟,每个面板显示的数字增加1。也就是说,在每秒结束时,显示9的面板现在显示0,显示0的面板现在显示1,显示1的面板现在显示2,依此类推。
当面板被暂停时,面板上显示的数字在接下来不会再次被改变。
瑶瑶姐姐可以在任何时间选择暂停这些面板中的一个,但只能选择一个面板暂停。然后,与之相邻的面板在1秒钟后暂停,与它相邻的面板的相邻的面板在2秒后暂停,依此类推。也就是说,如果您暂停面板x,则面板y将在秒钟后暂停。
例如,假设有4个面板,当数字9在第3个面板上时,它被选择暂停了。
面板12秒后暂停,因此它的数字为1
面板21秒后暂停,因此它的数字是0
面板41秒后暂停,因此它的数字为0
所得的4位数字为1090
暂停所有面板后,瑶瑶姐姐可以从左到右书写显示在面板上的数字,以形成一个n位数(可以由前导零组成)。您可以获得的最大数字是多少?

备注:


题解:找规律

代码:

    for(int i = 1; i <= n; i ++ )
        if(i <= 2) cout << (2 - i + 8) % 10;
        else cout << (i + 6) % 10;

4:小明认为,若一个十进制正整数是完美的,当且仅当它的各个位置的数字之和正好是10

例如第一个完美数是19,第二个完美数是28

给定一个正整数k,你的任务是找出第k个完美数。

输入描述:

仅一行一个整数。

输出描述:

仅一行一个整数。

代码:

int pd(int x)  //判断一个数是否是完美数

{

    int num = 0;
    while(x)
    {
        num += x % 10;
        x /= 10;
    }
    if(num == 10) return 1;
    else return 0;

}

5:在一所规模不大的高中,学生们决定去参加ICPC。这个目标要求尽可能多地组成三个人的团队,但由于只有6名学生希望参加,所以决定正好建立两个团队。
在练习赛后,编号为i的参赛者得到的分数是a_i。团队得分被定义为其成员的分数之和,高中管理层对是否有可能建立两支分数相同的队伍感兴趣。你的任务是回答这个问题。

题解:这题数据也有锅呜呜呜,有些代码应该过不了

代码:

     for(int i = 0; i < 6; i ++)
    {
        for(int j = 0; j < 6; j ++)
        {
            if(i == j) continue;
            for(int k = 0; k < 6; k ++)
            {
                if(k == i || k == j) continue;
                int sum = a[i] + a[j] + a[k];  // 选出的3个数的和
                if(num - sum == sum)  // 判断
                {
                    puts("YES"); return 0;
                }
            }
        }
    }
    puts("NO");

6:标题:小明想加入ACM集训队 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限

小明想加入学校的ACM集训队学习,教练给了他一份问卷调查,如果填写的内容全部符合教练预期,可以免考核入队。

问卷内容如下:

一、大学中你最想参加的社团/协会/部门是什么?

A、ACM集训队    B、其他    C、什么都不想参加

二、大学生涯希望如何度过?

A、不断学习,提升自己    B、不想学习,直接开摆    C、考试能混一混及格就好

三、加入ACM集训队后应该怎么做?

A、三天打鱼两天晒网    B、平时不训练,考核临时抱佛脚    C、认真学习和训练,通过每一次考核

四、以下规则哪一条更加适用于ACM基地?

A、训练时间内严禁在基地打游戏、看小说等    B、训练时间内可以随意讨论,哪怕声音特别大    C、随意旷训

五、如果在考核/比赛中被查到作弊或者违纪,你认为集训队会怎么做?

A、什么都不会做    B、考核/比赛成绩作废,情节严重全校通报批评    C、鼓励你下次接着干

假设现在你就是小明,你要怎么选择这些选项才能保证自己可以免考核入队?

题解:这题能错那么多次我是没有想到的,关键是还有人没有过,emmm

代码

printf("AACAB");

7:小明同学想去吃饭,来到饭店发现饭店正在宣传广告——回答问题就能免单。

给你一个数n,先把它转换成为二进制s,再将s拆分成多个的连续子段(要求子段的数量最少)。对于每个子段,要保证所有位置的数都是一样的,如果所有子段的长度都是偶数,则认为n是好的。

例如,,它将被划分为1100和 1111。它们的长度分别为224都是偶数,所以是好的。另一个例子,如果s是 ,它将被分成1110011000,它们的长度是3223。很明显,是不好的。

另外,你可以进行任意次数的操作:将这个数的二进制里的某一位的值进行改变(当然只能变成0或者1)。

你需要求出使这个n变好的最小操作次数,这个题目小明表示太简单了,可是老板不让小明回答,他想让小明指定一个人回答此问题。

(老板好可恶QAQ)
小明找到了你,现在请你帮小明回答此问题。

备注:

题解:先转换成二进制再两个两个一判断

代码:

    stack<int>q;
    while(n)
    {
        int x = n%2;
        q.push(x);
        n/=2;
    }
    string s;
    while(q.size())
    {
        s+=to_string(q.top());
        q.pop();
    }
    ll ans = 0;
    for(int i = 0;i < int(s.size());i += 2)
    {
        if(s[i] != s[i+1])
        ans ++;
    }

8:回文串”是一个正读和反读都一样的字符串,例如aba,abba。

瑶瑶姐姐非常喜欢回文串,她发现有一些回文串非常有趣,可以由更改一个字符串的部分字符而来。

更改的方式为:将其改为字母表中它的前一个字母,或者改为字母表中它的后一个字母。比如说,字母 p 能够被改成 o 或者 q,而字母 a 只能被改为 b,z 只能改为 y。

每个位置都只能执行一次(或者不执行)更改操作。

现在给你一个字符串s,问你是否可以通过以上操作得到一个“回文串”。

代码:

        while(T--)
        {
            int n;
            int f = 0;
            scanf("%d", &n);
            scanf("%s", s);
            for(int i = 0; i < n;i++){
            if(s[i] != s[n - 1 - i] && abs((int)(s[i] - s[n - 1 - i])) != 1){
            f = 1;
            break;
            }
        }
            if(!f)printf("YES\n");
        	else printf("NO\n");
        }

9:小明是一个追求完美的人,这天他发现完美数的定义:一个数如果能拆成两个大于0的偶数的和,就称这个数为完美的。

有个问题是:现给你一个数,问离这个数最近的两个完美数(如果有两个数距离一样,取较大的那一个)是什么?

小明看完这道题后很快就把代码写了出来:

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    if(n % 2 == 0printf("%d %d",n, n + 2);
    else printf("%d %d",n - 1, n + 1);
    return 0;
}

小明让你来帮他debug(调试代码),并且造了以下各组样例运行上述程序。

如果样例通过上述程序输出的值是符合问题要求的,请输出"AC";如果并不符合,请在第一行输出"WA",并在第二行输出正确答案

题解:没有什么好说的特判注意范围

10: 牛牛最近在玩一款游戏“炉石传说”,炉石传说是一款经典卡牌类对战的游戏。

游戏是两人对战,里面的卡牌分成两类,一类是法术牌,另一类是随从牌。

现在对方场上有n个随从,每个随从的血量为a_i,你的手牌中有m张“亵渎”,每张手牌的法力值耗费为b_i

“亵渎”的效果是对场面所有的随从造成1点伤害,如果有随从被击败(血量为0视为随从),则再次施放该法术。

问:一回合内(只有10点法力值),你能否能利用当前手牌将场面上所有随从击败。

题解:需要注意的是在一个回合,这个回合一共有10点

代码:

        qsort(b, m, sizeof(b[0]), cmp);//排序
        int ans = 10,cnt = 0;//初始法力水晶为10点
		for(int i = 0; i < m; ++i, ++cnt){//求出一回合可以打出的卡牌数
			if (ans < b[i]) {
				break;
			}
			ans -= b[i];
        }
        qsort(a, n, sizeof(a[0]), cmp);	//排序
        for(int i = 0; i < n - 1; ++i){
            if(a[i] == a[i + 1]){
                a[i] = 0;
            }
        }
        
        while(cnt--){
            int j = 1;//亵渎开始
            for(int i = 0; i < n; ++i){
                if(a[i] <= 0)continue;//死亡的随从跳过
                // if(a[i] == a[i + 1])continue;//两个相同的随从算一次,上面初始化了就不用
                if(a[i] - j == 0){//亵渎杀死此随从
                    j += 1;//再释放一次,可以理解为伤害+1
                }
                a[i] -= j;//亵渎对此随从造成伤害
            }
        }
        int f = 1;
        for(int i = 0; i < n; ++i){
            if(a[i] > 0){//如果有随从活着
                f = 0;
                break;
            }
        }
        if(f)printf("YES\n");
        else printf("NO\n");

总体来说比第一次考核难,但是需要一点点思维,也没有很难,部分题目数据有点水,在此出题人员表示歉意