第一次排位賽題解

第一次排位賽題解

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

  • 其實每次去哪兩個都可以,但是官方題解是每次取最大的兩個,可能他想貪心一下
    在這裏插入圖片描述
    所以,最後是啥呢?啥也不是!就是審題不夠細,思維跟不上,不過通過這次排位賽也學到了不少新東西。希望可以借這次機會有所進步。

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