Week13作業

A - TT 的神祕任務1(必做)

這一天,TT 遇到了一個神祕人。
神祕人給了兩個數字,分別表示 n 和 k,並要求 TT 給出 k 個奇偶性相同的正整數,使得其和等於 n。
例如 n = 10,k = 3,答案可以爲 [4 2 4]。
TT 覺得這個任務太簡單了,不願意做,你能幫他完成嗎?
本題是SPJ

輸入

第一行一個整數 T,表示數據組數,不超過 1000。
之後 T 行,每一行給出兩個正整數,分別表示 n(1 ≤ n ≤ 1e9)、k(1 ≤ k ≤ 100)。

輸出

如果存在這樣 k 個數字,則第一行輸出 “YES”,第二行輸出 k 個數字。
如果不存在,則輸出 “NO”。

樣例輸入

8
10 3
100 4
8 7
97 2
8 8
3 10
5 3
1000000000 9

樣例輸出

YES
4 2 4
YES
55 5 5 35
NO
NO
YES
1 1 1 1 1 1 1 1
NO
YES
3 1 1
YES
111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111120

思路

綜述

T1,找到一種解題思路即可;可如下所示
1)要麼全是偶數,則可以爲k-1個2,剩餘的判斷是否是偶數
2)要麼全是奇數,則可以爲k-1個1,剩餘的判斷是否是奇數
3)不能表達

代碼

#include <iostream>

using namespace std;

int T;
int n,k;

void work(int n,int k){
	int term1;
	//奇數 
	term1 = n;
	for(int i=0;i<k-1;i++){
		term1--;
	}
	if(term1<=0){
		cout<<"NO"<<endl;
		return;
	}
	if(term1 % 2 == 1){
		cout<<"YES"<<endl;
		cout<<term1;
		for(int i=0;i<k-1;i++)cout<<" "<<1;
		cout<<endl;
		return;
	}
	//偶數
	term1 = n;
	for(int i=0;i<k-1;i++){
		term1 -= 2;
	}	 
	if(term1<=0){
		cout<<"NO"<<endl;
		return;
	}
	if(term1 % 2 == 0){
		cout<<"YES"<<endl;
		cout<<term1;
		for(int i=0;i<k-1;i++)cout<<" "<<2;
		cout<<endl;
		return;
	}	
	cout<<"NO"<<endl;
}
int main(){
	cin>>T;
		for(int i=0;i<T;i++){
			cin>>n>>k;
			work(n,k);
		}
}

B - TT 的神祕任務2(必做)

在你們的幫助下,TT 輕鬆地完成了上一個神祕任務。
但是令人沒有想到的是,幾天後,TT 再次遇到了那個神祕人。
而這一次,神祕人決定加大難度,並許諾 TT,如果能夠完成便給他一個獎勵。
任務依舊只給了兩個數字,分別表示 n 和 k,不過這一次是要求 TT 給出無法被 n 整除的第 k 大的正整數。
例如 n = 3,k = 7,則前 7 個無法被 n 整除的正整數爲 [1 2 4 5 7 8 10],答案爲 10。
好奇的 TT 想要知道獎勵究竟是什麼,你能幫幫他嗎?

輸入

第一行一個整數 T,表示數據組數,不超過 1000。
之後 T 行,每一行給出兩個正整數,分別表示 n(2 ≤ n ≤ 1e9)、k(1 ≤ k ≤ 1e9)。

輸出

對於每一組數據,輸出無法被 n 整除的第 k 大的正整數。

樣例輸入

6
3 7
4 12
2 1000000000
7 97
1000000000 1000000000
2 1

樣例輸出

10
15
1999999999
113
1000000001
1

思路

綜述

可以如下思考:

  • 前n-1個不能被n整除的數爲1~n-1;
  • 接下來的n-1個爲(1~n-1)+n-1;

上面兩條說明,不能被n整除的數可以分組,每組含n-1個數字且連續,並且兩組之間僅僅差1;則第K大的數,找到指定組然後找到指定位置即可;
複雜度常數級

總結

簡單的邏輯題

代碼

#include <iostream>

using namespace std;
int T;
int n,k;

void work(int n,int k){
	int gp = n-1;
	int num = k/gp;
	if( k % gp == 0 ){
		int ans = num*gp;
		ans += num-1;
		cout<<ans<<endl;
		return;
	}
	int ans = num*gp + num;
	int pos = k - gp*num;
	ans+=pos;
	cout<<ans<<endl;
	return;
}

int main(){
	cin>>T;
	for(int i;i<T;i++){
		cin>>n>>k;
		work(n,k);
	}
}

C - TT 的獎勵(必做)

在大家不辭辛勞的幫助下,TT 順利地完成了所有的神祕任務。
神祕人很高興,決定給 TT 一個獎勵,即白日做夢之撿貓咪遊戲。
撿貓咪遊戲是這樣的,貓咪從天上往下掉,且只會掉在 [0, 10] 範圍內,具體的座標範圍如下圖所示。
在這裏插入圖片描述
TT 初始站在位置五上,且每秒只能在移動不超過一米的範圍內接住掉落的貓咪,如果沒有接住,貓咪就會跑掉。例如,在剛開始的一秒內,TT 只能接到四、五、六這三個位置其中一個位置的貓咪。
喜愛貓咪的 TT 想要接住儘可能多的貓咪,你能幫幫他嗎?

輸入

多組樣例。每組樣例輸入一個 m (0 < m < 100000),表示有 m 只貓咪。
在接下來的 m 行中,每行有兩個整數 a b (0 < b < 100000),表示在第 b 秒的時候有一隻貓咪掉落在 a 點上。
注意,同一個點上同一秒可能掉落多隻貓咪。m = 0 時輸入結束。

輸出

輸出一個整數 x,表示 TT 可能接住的最多的貓咪數。

樣例輸入

6
5 1
4 1
6 1
7 2
7 2
8 3
0

樣例輸出

4

思路

綜述

一道動態規劃題;
設dp[i][j]爲j秒時位置i處接收最多貓咪;
初始化:

  • 每個點dp[i][j]爲該處該秒下落的貓咪數量;
  • 0~3 8~10八個點的某些時間點應爲0,因爲前幾秒到達不了
    舉例:0號位置的1,2,3,4都應該爲0,因爲開始四秒內到達不了0號位置;

轉移方程

dp[j][i] += max(dp[j][i-1],max(dp[j-1][i-1],dp[j+1][i-1]));

總結

動態規劃題稍微有點眉目;
感覺類似遞推的題目,設置初始值,然後依次向後運算,最終找到答案;

代碼

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
const int maxn=1e5+50;
int maxt;
int dp[20][maxn];
int a,b;
void init(){
	for(int j=0;j<12;j++)
		for(int i=0;i<maxn;i++)
		dp[j][i]=0;
		
		maxt=-10;
}

int main(){
	while(1){
		init();
		cin>>m;
		if(m==0)break;
		
		for(int i=0;i<m;i++){
			cin>>a>>b;
			dp[a+1][b]++;
			maxt = max(maxt,b);
		}
		//初始化
		for(int i=0;i<=4;i++){
			for(int j=0;j<=5-i;j++){
				dp[i][j]=0;
			}
		} 
		for(int i=8;i<=12;i++){
			for(int j=0;j<=i-7;j++){
				dp[i][j]=0;
			}
		}
		
		for(int i=2;i<=maxt;i++){
			for(int j=1;j<=11;j++){
				dp[j][i] += max(dp[j][i-1],max(dp[j-1][i-1],dp[j+1][i-1]));
			}
		}
		
		int num=-1;
		for(int i=0;i<=12;i++){
			num = max(dp[i][maxt],num);
		} 
		cout<<num<<endl;
	}
}

D - TT 的蘋果樹(選做)

輸入

輸出

樣例輸入


樣例輸出


思路

綜述

總結

代碼


E - TT 的神祕任務3(選做)

輸入

輸出

樣例輸入


樣例輸出


思路

綜述

總結

代碼


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