2020年HZNU天梯訓練賽 Round 7
2020年HZNU天梯訓練賽 Round 7
時間:2020.7.23 12 170
完成情況:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ | √ | ※ | ||||
√ 當場做出來 ※做了一半來 ✘補題補出來
7-1 天梯賽座位分配 (20分)
天梯賽每年有大量參賽隊員,要保證同一所學校的所有隊員都不能相鄰,分配座位就成為一件比較麻煩的事情。為此我們制定如下策略:假設某賽場有 N 所學校參賽,第 i 所學校有 M[i] 支隊伍,每隊 10 位參賽選手。令每校選手排成一列縱隊,第 i+1 隊的選手排在第 i 隊選手之後。從第 1 所學校開始,各校的第 1 位隊員順次入座,然後是各校的第 2 位隊員…… 以此類推。如果最後只剩下 1 所學校的隊伍還沒有分配座位,則需要安排他們的隊員隔位就坐。本題就要求你編寫程式,自動為各校生成隊員的座位號,從 1 開始編號。
輸入格式:
輸入在一行中給出參賽的高校數 N (不超過100的正整數);第二行給出 N 個不超過10的正整數,其中第 i 個數對應第 i 所高校的參賽隊伍數,數字間以空格分隔。
輸出格式:
從第 1 所高校的第 1 支隊伍開始,順次輸出隊員的座位號。每隊佔一行,座位號間以 1 個空格分隔,行首尾不得有多餘空格。另外,每所高校的第一行按“#X”輸出該校的編號X,從 1 開始。
輸入樣例:
3
3 4 2
輸出樣例:
#1 1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 63 65 67 69 71 73 75 77 79 #2 2 5 8 11 14 17 20 23 26 29 32 35 38 41 44 47 50 53 56 59 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 #3 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60
#include<bits/stdc++.h> using namespace std; //用二維陣列第二位與10的關係將三維陣列化簡為二維 int a[102][102],b[102][102]; int main() { int n,m,maxx=0,x=1,y=-1; cin>>n; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(int i=0;i<n;i++) { cin>>m;maxx=m>maxx?m:maxx; for(int j=0;j<10*m;j++)a[i][j]=1;//標記一下總座位數 } for(int i=0;i<10*maxx;i++) { for(int j=0;j<n;j++) { if(a[j][i]) { if(y!=j) b[j][i]=x++,y=j; else{x+=1;b[j][i]=x++;y=j;} } } } for(int i=1;i<=n;i++) { cout<<"#"<<i<<endl; for(int j=0;j<10*maxx;j++) { if(b[i-1][j]) { cout<<b[i-1][j]; if((j+1)%10!=0)cout<<" "; else if((j+1)%10==0)cout<<endl; } //if(b[i][j])printf("%d%c",b[i][j],(j+1)%10==0?'\n':' '); } } return 0; } /*#include<bits/stdc++.h>//錯誤原因 當一所學校編完了就不再編所以還需要記錄 using namespace std; int main() { int n,m,x; cin>>n; for(int i=1;i<=n;i++) { cin>>m;x=i; cout<<"#"<<x<<endl; for(int j=0;j<m;j++) { for(int k=0;k<10;k++) { cout<<x; if(k!=9)cout<<" "; x+=n; } cout<<endl; } } return 0; }*/
7-2 倒數第N個字串 (15分)
給定一個完全由小寫英文字母組成的字串等差遞增序列,該序列中的每個字串的長度固定為 L,從 L 個 a 開始,以 1 為步長遞增。例如當 L 為 3 時,序列為 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz }。這個序列的倒數第27個字串就是 zyz。對於任意給定的 L,本題要求你給出對應序列倒數第 N 個字串。
輸入格式:
輸入在一行中給出兩個正整數 L(2 ≤ L ≤ 6)和 N(≤105)。
輸出格式:
在一行中輸出對應序列倒數第 N 個字串。題目保證這個字串是存在的。
輸入樣例:
3 7417
輸出樣例:
pat
#include<bits/stdc++.h>
using namespace std;
char s[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int main()
{
int L,N,flag;
char ans[6];
cin>>L>>N;
for(int i=1;i<=L;i++)
{
flag=0;
if(i==1)
{
if(N%26==0){ans[L-i]=s[0];N=N/26-1;flag=1;}
else ans[L-i]=s[26-N%26];
}
else ans[L-i]=s[26-N%26-1];
if(flag==0)N=N/26;
}
cout<<ans;
return 0;
}
7-3 打折 (5分)
去商場淘打折商品時,計算打折以後的價錢是件頗費腦子的事情。例如原價 ¥988,標明打 7 折,則折扣價應該是 ¥988 x 70% = ¥691.60。本題就請你寫個程式替客戶計算折扣價。
輸入格式:
輸入在一行中給出商品的原價(不超過1萬元的正整數)和折扣(為[1, 9]區間內的整數),其間以空格分隔。
輸出格式:
在一行中輸出商品的折扣價,保留小數點後 2 位。
輸入樣例:
988 7
輸出樣例:
691.60
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
printf("%.2lf",1.0*a*b/10);
return 0;
}
7-4 2018我們要贏 (5分)
2018年天梯賽的註冊邀請碼是“2018wmyy”,意思就是“2018我們要贏”。本題就請你用漢語拼音輸出這句話。
輸入格式:
本題沒有輸入。
輸出格式:
在第一行中輸出:“2018”;第二行中輸出:“wo3 men2 yao4 ying2 !”。
輸入樣例:
本題沒有輸入。
輸出樣例:
2018
wo3 men2 yao4 ying2 !
2018
wo3 men2 yao4 ying2 !
7-5 電子汪 (10分)
據說汪星人的智商能達到人類 4 歲兒童的水平,更有些聰明汪會做加法計算。比如你在地上放兩堆小球,分別有 1 只球和 2 只球,聰明汪就會用“汪!汪!汪!”表示 1 加 2 的結果是 3。
本題要求你為電子寵物汪做一個模擬程式,根據電子眼識別出的兩堆小球的個數,計算出和,並且用汪星人的叫聲給出答案。
輸入格式:
輸入在一行中給出兩個 [1, 9] 區間內的正整數 A 和 B,用空格分隔。
輸出格式:
在一行中輸出 A + B 個Wang!
。
輸入樣例:
2 1
輸出樣例:
Wang!Wang!Wang!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
for(int i=0;i<a+b;i++)
cout<<"Wang!";
return 0;
}
7-6 福到了 (15分)
“福”字倒著貼,寓意“福到”。不論到底算不算民俗,本題且請你編寫程式,把各種漢字倒過來輸出。這裡要處理的每個漢字是由一個 N × N 的網格組成的,網格中的元素或者為字元 @
或者為空格。而倒過來的漢字所用的字元由裁判指定。
輸入格式:
輸入在第一行中給出倒過來的漢字所用的字元、以及網格的規模 N (不超過100的正整數),其間以 1 個空格分隔;隨後 N 行,每行給出 N 個字元,或者為 @
或者為空格。
輸出格式:
輸出倒置的網格,如樣例所示。但是,如果這個字正過來倒過去是一樣的,就先輸出bu yong dao le
,然後再用輸入指定的字元將其輸出。
輸入樣例 1:
$ 9
@ @@@@@
@@@ @@@
@ @ @
@@@ @@@
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
@ @ @ @
@ @@@@@
輸出樣例 1:
$$$$$ $
$ $ $ $
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
$$$ $$$
$ $ $
$$$ $$$
$$$$$ $
輸入樣例 2:
& 3
@@@
@
@@@
輸出樣例 2:
bu yong dao le
&&&
&
&&&
#include<bits/stdc++.h>
using namespace std;
string s[101];
int main()
{
int n,flag=0;
char c;
cin>>c>>n;
//cout<<c<<n;
getchar();
for(int i=0;i<n;i++)
{
getline(cin,s[i]);
//for(int j=0;j<n;j++)
// scanf("%c",s[i][j]);
//getchar();
}
//cout<<s[0][0];
//cin.getline(s[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(s[i][j]!=' ') s[i][j]=c;
else s[i][j]=' ';
}
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(s[i][j]!=s[n-i-1][n-j-1])flag=1;
if(flag==0)cout<<"bu yong dao le"<<endl;
for(int i=n-1;i>=0;i--)
{
for(int j=n-1;j>=0;j--)
cout<<s[i][j];
cout<<endl;
}
return 0;
}
7-7 誰是贏家 (10分)
某電視臺的娛樂節目有個表演評審環節,每次安排兩位藝人表演,他們的勝負由觀眾投票和 3 名評委投票兩部分共同決定。規則為:如果一位藝人的觀眾票數高,且得到至少 1 名評委的認可,該藝人就勝出;或藝人的觀眾票數低,但得到全部評委的認可,也可以勝出。節目保證投票的觀眾人數為奇數,所以不存在平票的情況。本題就請你用程式判斷誰是贏家。
輸入格式:
輸入第一行給出 2 個不超過 1000 的正整數 Pa 和 Pb,分別是藝人 a 和藝人 b 得到的觀眾票數。題目保證這兩個數字不相等。隨後第二行給出 3 名評委的投票結果。數字 0 代表投票給 a,數字 1 代表投票給 b,其間以一個空格分隔。
輸出格式:
按以下格式輸出贏家:
The winner is x: P1 + P2
其中 x
是代表贏家的字母,P1
是贏家得到的觀眾票數,P2
是贏家得到的評委票數。
輸入樣例:
327 129
1 0 1
輸出樣例:
The winner is a: 327 + 1
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,x,cnt=0;
cin>>a>>b;
for(int i=0;i<3;i++)
{
cin>>x;
if(x==1)cnt++;
}
if((a>b&&cnt!=3)||(cnt==0))cout<<"The winner is a: "<<a<<" + "<<3-cnt;
else cout<<"The winner is b: "<<b<<" + "<<cnt;
return 0;
}
7-8 猜數字 (20分)
一群人坐在一起,每人猜一個 100 以內的數,誰的數字最接近大家平均數的一半就贏。本題就要求你找出其中的贏家。
輸入格式:
輸入在第一行給出一個正整數N(≤104)。隨後 N 行,每行給出一個玩家的名字(由不超過8個英文字母組成的字串)和其猜的正整數(≤ 100)。
輸出格式:
在一行中順序輸出:大家平均數的一半(只輸出整數部分)、贏家的名字,其間以空格分隔。題目保證贏家是唯一的。
輸入樣例:
7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62
輸出樣例:
22 Amy
#include<bits/stdc++.h>
using namespace std;
struct node {char name[10];int n;}id[10005];//名字開8會卡測試點2、3???
int main()
{
int n,sum=0,aver,minn=200,mini=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>id[i].name>>id[i].n;
sum+=id[i].n;
}
aver=sum/n/2;
for(int i=0;i<n;i++)
{
if(abs(aver-id[i].n)<minn){minn=abs(aver-id[i].n);mini=i;}
}
cout<<aver<<" "<<id[mini].name;
return 0;
}
7-9 分而治之 (25分)
分而治之,各個擊破是兵家常用的策略之一。在戰爭中,我們希望首先攻下敵方的部分城市,使其剩餘的城市變成孤立無援,然後再分頭各個擊破。為此參謀部提供了若干打擊方案。本題就請你編寫程式,判斷每個方案的可行性。
輸入格式:
輸入在第一行給出兩個正整數 N 和 M(均不超過10 000),分別為敵方城市個數(於是預設城市從 1 到 N 編號)和連線兩城市的通路條數。隨後 M 行,每行給出一條通路所連線的兩個城市的編號,其間以一個空格分隔。在城市資訊之後給出參謀部的系列方案,即一個正整數 K (≤ 100)和隨後的 K 行方案,每行按以下格式給出:
Np v[1] v[2] ... v[Np]
其中 Np
是該方案中計劃攻下的城市數量,後面的系列 v[i]
是計劃攻下的城市編號。
輸出格式:
對每一套方案,如果可行就輸出YES
,否則輸出NO
。
輸入樣例:
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 10
2 4
5
4 10 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2
輸出樣例:
NO
YES
YES
NO
NO
#include<bits/stdc++.h>
using namespace std;
vector<int> v[10005];
//無向圖的連通
int main()
{
int n,m,a,b,k,y,z,flag,c[10005];
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
cin>>k;
while(k--)
{
memset(c,0,sizeof(c));flag=0;
cin>>y;
while(y--){cin>>z;c[z]=1;}
for(int i=1;i<=n;i++)
{
for(int j=0;j<v[i].size();j++)
{
if(c[i]==0&&c[v[i][j]]==0){flag=1;break;}
}
}
if(flag==0)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
7-10 小字輩 (25分)
本題給定一個龐大家族的家譜,要請你給出最小一輩的名單。
輸入格式:
輸入在第一行給出家族人口總數 N(不超過 100 000 的正整數) —— 簡單起見,我們把家族成員從 1 到 N 編號。隨後第二行給出 N 個編號,其中第 i 個編號對應第 i 位成員的父/母。家譜中輩分最高的老祖宗對應的父/母編號為 -1。一行中的數字間以空格分隔。
輸出格式:
首先輸出最小的輩分(老祖宗的輩分為 1,以下逐級遞增)。然後在第二行按遞增順序輸出輩分最小的成員的編號。編號間以一個空格分隔,行首尾不得有多餘空格。
輸入樣例:
9
2 6 5 5 -1 5 6 4 7
輸出樣例:
4
1 9
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];
int f(int x)
{
if(a[x]==-1)return b[x]=1;
if(b[x]) return b[x];
else return b[x]=f(a[x])+1;
}
int main()
{
int n,minn=0,flag=1;
cin>>n;
for(int i=1;i<=n;i++)a[i]=i;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)minn=f(i)>minn?f(i):minn;
cout<<minn<<endl;
for(int i=1;i<=n;i++)
{
if(b[i]==minn)
{
if(flag) {cout<<i;flag=0;}
else cout<<" "<<i;
}
}
return 0;
}
7-11 名人堂與代金券 (25分)
對於在中國大學MOOC(http://www.icourse163.org/ )學習“資料結構”課程的學生,想要獲得一張合格證書,總評成績必須達到 60 分及以上,並且有另加福利:總評分在 [G, 100] 區間內者,可以得到 50 元 PAT 代金券;在 [60, G) 區間內者,可以得到 20 元PAT代金券。全國考點通用,一年有效。同時任課老師還會把總評成績前 K 名的學生列入課程“名人堂”。本題就請你編寫程式,幫助老師列出名人堂的學生,並統計一共發出了面值多少元的 PAT 代金券。
輸入格式:
輸入在第一行給出 3 個整數,分別是 N(不超過 10 000 的正整數,為學生總數)、G(在 (60,100) 區間內的整數,為題面中描述的代金券等級分界線)、K(不超過 100 且不超過 N 的正整數,為進入名人堂的最低名次)。接下來 N 行,每行給出一位學生的賬號(長度不超過15位、不帶空格的字串)和總評成績(區間 [0, 100] 內的整數),其間以空格分隔。題目保證沒有重複的賬號。
輸出格式:
首先在一行中輸出發出的 PAT 代金券的總面值。然後按總評成績非升序輸出進入名人堂的學生的名次、賬號和成績,其間以 1 個空格分隔。需要注意的是:成績相同的學生享有並列的排名,排名並列時,按賬號的字母序升序輸出。
輸入樣例:
10 80 5
[email protected] 78
[email protected] 87
[email protected] 65
[email protected] 96
[email protected] 39
[email protected] 87
[email protected] 80
[email protected] 88
[email protected] 80
[email protected] 70
輸出樣例:
360
1 [email protected] 96
2 [email protected] 88
3 [email protected] 87
3 [email protected] 87
5 [email protected] 80
5 [email protected] 80
#include <bits/stdc++.h>
using namespace std;
//≈點贊狂魔
struct node{string name;int score;}id[10005];
bool comp(node a, node b)
{
if(a.score != b.score) return a.score > b.score;
else return a.name < b.name;
}
int main()
{
int n,g,k,sum=0;
cin>>n>>g>>k;
for(int i=0;i<n;i++)
{
cin>>id[i].name>>id[i].score;
if(id[i].score>=g) sum+=50;
else if(id[i].score>=60) sum+=20;
}
cout<<sum<<endl;
sort(id,id+n,comp);
int cnt;
for(int i=1;i<n;i++)
{
if(i==1||id[i-1].score !=id[i-2].score){cnt=i;if(cnt>k) break;cout<<i;}
else cout<<cnt;
cout<<" "<<id[i-1].name<<" "<<id[i-1].score<<endl;
}
return 0;
}
7-12 秀恩愛分得快 (25分)
古人云:秀恩愛,分得快。
網際網路上每天都有大量人釋出大量照片,我們通過分析這些照片,可以分析人與人之間的親密度。如果一張照片上出現了 K 個人,這些人兩兩間的親密度就被定義為 1/K。任意兩個人如果同時出現在若干張照片裡,他們之間的親密度就是所有這些同框照片對應的親密度之和。下面給定一批照片,請你分析一對給定的情侶,看看他們分別有沒有親密度更高的異性朋友?
輸入格式:
輸入在第一行給出 2 個正整數:N(不超過1000,為總人數——簡單起見,我們把所有人從 0 到 N-1 編號。為了區分性別,我們用編號前的負號表示女性)和 M(不超過1000,為照片總數)。隨後 M 行,每行給出一張照片的資訊,格式如下:
K P[1] ... P[K]
其中 K(≤ 500)是該照片中出現的人數,P[1] ~ P[K] 就是這些人的編號。最後一行給出一對異性情侶的編號 A 和 B。同行數字以空格分隔。題目保證每個人只有一個性別,並且不會在同一張照片裡出現多次。
輸出格式:
首先輸出 A PA
,其中 PA
是與 A
最親密的異性。如果 PA
不唯一,則按他們編號的絕對值遞增輸出;然後類似地輸出 B PB
。但如果 A
和 B
正是彼此親密度最高的一對,則只輸出他們的編號,無論是否還有其他人並列。
輸入樣例 1:
10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2
輸出樣例 1:
-3 2
2 -5
2 -6
輸入樣例 2:
4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2
-3 2
輸出樣例 2:
-3 2
7-13 程式碼排版 (30分)
某程式設計大賽中設計有一個挑戰環節,選手可以檢視其他選手的程式碼,發現錯誤後,提交一組測試資料將對手挑落馬下。為了減小被挑戰的機率,有些選手會故意將程式碼寫得很難看懂,比如把所有回車去掉,提交所有內容都在一行的程式,令挑戰者望而生畏。
為了對付這種選手,現請你編寫一個程式碼排版程式,將寫成一行的程式重新排版。當然要寫一個完美的排版程式可太難了,這裡只簡單地要求處理C語言裡的for、while、if-else這三種特殊結構,而將其他所有句子都當成順序執行的語句處理。輸出的要求如下:
- 預設程式起始沒有縮排;每一級縮排是 2 個空格;
- 每行開頭除了規定的縮排空格外,不輸出多餘的空格;
- 順序執行的程式體是以分號“;”結尾的,遇到分號就換行;
- 在一對大括號“{”和“}”中的程式體輸出時,兩端的大括號單獨佔一行,內部程式體每行加一級縮排,即:
{
程式體
}
- for的格式為:
for (條件) {
程式體
}
- while的格式為:
while (條件) {
程式體
}
- if-else的格式為:
if (條件) {
程式體
}
else {
程式體
}
輸入格式:
輸入在一行中給出不超過 331 個字元的非空字串,以回車結束。題目保證輸入的是一個語法正確、可以正常編譯執行的 main 函式模組。
輸出格式:
按題面要求的格式,輸出排版後的程式。
輸入樣例:
int main() {int n, i; scanf("%d", &n);if( n>0)n++;else if (n<0) n--; else while(n<10)n++; for(i=0; i<n; i++ ){ printf("n=%d\n", n);}return 0; }
輸出樣例:
int main()
{
int n, i;
scanf("%d", &n);
if ( n>0) {
n++;
}
else {
if (n<0) {
n--;
}
else {
while (n<10) {
n++;
}
}
}
for (i=0; i<n; i++ ) {
printf("n=%d\n", n);
}
return 0;
}
7-14 至多刪三個字元 (35分)
給定一個全部由小寫英文字母組成的字串,允許你至多刪掉其中 3 個字元,結果可能有多少種不同的字串?
輸入格式:
輸入在一行中給出全部由小寫英文字母組成的、長度在區間 [4, 106] 內的字串。
輸出格式:
在一行中輸出至多刪掉其中 3 個字元後不同字串的個數。
輸入樣例:
ababcc
輸出樣例:
25
提示:
刪掉 0 個字元得到 "ababcc"。
刪掉 1 個字元得到 "babcc", "aabcc", "abbcc", "abacc" 和 "ababc"。
刪掉 2 個字元得到 "abcc", "bbcc", "bacc", "babc", "aacc", "aabc", "abbc", "abac" 和 "abab"。
刪掉 3 個字元得到 "abc", "bcc", "acc", "bbc", "bac", "bab", "aac", "aab", "abb" 和 "aba"。
7-15 神壇 (30分)
在古老的邁瑞城,巍然屹立著 n 塊神石。長老們商議,選取 3 塊神石圍成一個神壇。因為神壇的能量強度與它的面積成反比,因此神壇的面積越小越好。特殊地,如果有兩塊神石座標相同,或者三塊神石共線,神壇的面積為 0.000
。
長老們發現這個問題沒有那麼簡單,於是委託你程式設計解決這個難題。
輸入格式:
輸入在第一行給出一個正整數 n(3 ≤ n ≤ 5000)。隨後 n 行,每行有兩個整數,分別表示神石的橫座標、縱座標(−109≤ 橫座標、縱座標 <109)。
輸出格式:
在一行中輸出神壇的最小面積,四捨五入保留 3 位小數。
輸入樣例:
8
3 4
2 4
1 1
4 1
0 3
3 0
1 3
4 2
輸出樣例:
0.500
樣例解釋
輸出的數值等於圖中紅色或紫色框線的三角形的面積。