第一次排位赛题解

第一次排位赛题解

A - Sky数

  第一题是典型的进制转换问题,包括我在内大家最常想到一种代码方式就是如下:
(调用函数计算12进制和16进制的sum值)

int sixth(int n){
   
   
	int sum = 0;
	while(n != 0){
   
   
		sum += n%16;
		n/=16;        
	}
	return sum;
}

int twelve(int n){
   
   
	int sum = 0;
	while(n != 0){
   
   
		sum += n%12;
		n/=12;
	}
	return sum;
}

要注意到以下三点:

  • 进制转换(十进制转换为十六进制,十进制转换为十二进制)
  • 在每个进制下对应的位数要求
  • 打印结果

B - 哥德巴赫来了可能有用吧

  首先刚看到这个题目的时候我的内心是拒绝的,在我好不容易敲完这个代码后得到的结果却是:在这里插入图片描述z
   很常见的错误,就是多层循环嵌套导致超时…
这道题要注意的是:

  • 哥德巴赫猜想:大于2的偶数可以分解成两个素数之和
  • 10000以内的素数:素数筛法———用筛法求素数
  • 还有要注意14=7+7是不可以的!
    接下来只需如此简短代码即可实现:
    在这里插入图片描述
    调用函数:
    在这里插入图片描述



C - 咦!这是嘛呀!

  想要成功Accept这道题,首先需要了解&(与运算),xor(异或运算)符号,奉上学长手绘真值表:在这里插入图片描述

  • 如果A&B等于0 那么C可以给最小的0,但是题目要特判,所以为1
  • A&B不等于0,那么就需要让C与他们共同为1的一致就好这样能得到最小值
typedef long long 11;
int main()
{
   
   
	int T;
	cin >> T;
	ll a,b;
	while(T--){
   
   
		cin>>a>>b;
		ll c = a&b;
		printf("%lld\n",c?c:1);
	}
	return 0;
}

D - 倩姐的自我突破

  在我努力半个小时后得出Time limit的结果后心情是这样的:在这里插入图片描述
但是万万没想到的是这道题稍微找找规律就能发现其中的猫腻

输入样例 输出样例
2 1
3 2
4 3
n n-1

好家伙!我直呼好家伙!就当又学到一招吧,下次看到题先花两分钟时间观察一下输入输出之间是否存在某种规律…

E - 看看就好,劝一下自己

  这道题是我认为本次考试最温柔的题了,可是即使如此我却得到了两次wrong answer,原因就是输出格式,切记YES和yes、Yes是完全不同的😭。
代码奉上:

#include <stdio.h>
int main()
{
   
   
	int i,j;
	unsigned __int64 n,a,b,sum1,sum2;
	scanf("%I64u",&n);
	for(i=0;i<n;i++){
   
   
		sum1=0;
		sum2=0;
		scanf("%I64u %I64u",&a,&b);
		for(j=1;j<=a/2;j++){
   
   
			if(a%j==0)
				sum1+=j;
		}
		for(j=1;j<=b/2;j++){
   
   
			if(b%j==0)
				sum2+=j;
		}
		if(sum1==b&&sum2==a){
   
   
			printf("YES\n");
		}else{
   
   
			printf("NO\n");
		}
	}
	return 0;
}

当然这是每个人都能想到的,然而在今晚学长的讲解下又得到了可以优化的地方,那就是约和数打表!
简单来说就是把每个数的约数和求出来存在数组里,在每次用的时候调用次函数即可,目的是大大缩短程序运行时间。
在这里插入图片描述

F - 熊熊的尝试

  本题涉及到了最简单的博弈论——巴什博弈(只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次最少取一个,最多取m个。最后取光者得胜。)
思考:最多取m个,如果剩下m+1个是不是无论第一个人如何取,后手都能一次取完
也就是说:无论他们前边如何拿如果n=(m+1)r+s(换句话说就是当先手拿走s个时,后手总能保证剩下的为m+1的整数倍,则后手必胜,否则先手必胜)
例如:先手拿走s个,后手拿走k个保证剩下的是(m+1)的整数倍,则后手必胜,如果先手拿走s个使得剩下的为(m+1)的整数倍,则先手必胜


if(n%(m+1)==0)
	printf("second\n");
else
	printf("first\n");

对,没错,这就结束了!

G - 该烂怂塔,有啥看的

  从下往上找,是不是能找到两个中最大的到上一节点,以此类推
如图:
在这里插入图片描述

for(int i=n-1;i>=0;i--){
   
   
	for(int j=0;j<=i;++j){
   
   
		dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
	}
}

而如果从上往下找的话就必须要同时从广度和深度进行,比较所有的值再得出最大值(比较复杂,不推荐)

H - Tyloo的S1mple本人

  这道题直接暴力就行,找出满足n=3 * i + 5 * j + 7 * k的i,j,k即可。
在这里插入图片描述

I - 可鞥吧

  用学长的话来说,又是一道“白给”的题😭,这道题涉及到了一点点贪心算法:

  在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。”

他每次都想把次多的倒入的最多的里边,这样最多的就是最终解:
在这里插入图片描述

J - 最后是啥呢

题意:

  • 就是给你1到n的数列,让后你每次操作取出a、b放入 ,然后n-1次后就会剩下一个数

  • 让你想办法,如何操才能使最后的数最小,最小是多少,每次操作取那两个数

题解:

  • 明确你不论如何操作最小值都会是2

  • 其实每次去哪两个都可以,但是官方题解是每次取最大的两个,可能他想贪心一下
    在这里插入图片描述
    所以,最后是啥呢?啥也不是!就是审题不够细,思维跟不上,不过通过这次排位赛也学到了不少新东西。希望可以借这次机会有所进步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章