文章目錄
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(選做)
輸入
輸出
樣例輸入
樣例輸出
思路
綜述
總結
代碼