2021级新生个人训练赛第38场
問題 A: chicken
題目描述
小 x 非常喜歡小雞翅。他得知 NSC 超市為了吸引顧客,舉行了如下的活動:
一旦有顧客在其他超市找到更便宜的小雞翅,NSC 超市將免費送給顧客 1000g 小雞翅。小 x 為了盡可能的省錢,走遍了各大超市,統計了小雞翅的價格。NSC 的工作人員通過不法手段盜取了這些資料。現在 NSC 的工作人員希望你能幫他們定一個盡可能低的價格(1000克 小雞翅的價格),使小 x 吃不到免費的小雞翅。
輸入
第一行兩個正整數 XNSC (1 ≤ XNSC ≤ 100) 和 YNSC (1 ≤ YNSC ≤1000),表示現在在 NSC 超市,YNSC 克 小雞翅要賣 XNSC 元。
第二行一個正整數 N,表示其他超市的個數。
接下來 N 行,每行兩個正整數 Xi(1 ≤ Xi ≤ 100) 和 Yi(1 ≤ Yi ≤ 1000),表示在第 i 家超市,Yi 克小雞翅賣 Xi 元。
輸出
有且僅有一行,包含一個實數 A,表示 NSC 超市可以定的最高價格:A 元/千克。A 保留兩位小數。
樣例輸入 Copy
5 100
3
4 100
3 100
7 100
樣例輸出 Copy
30.00
簽到題
#include<iostream> #include<algorithm> #include<iomanip> using namespace std; double x[100001],y[100001],s[100001]; int main() {cin>>x[0]>>y[0];s[0]=(x[0]*(1000*1.0/y[0]));int n;cin>>n;for(int i=1;i<=n;i++){cin>>x[i]>>y[i];s[i]=(x[i]*(1000*1.0/y[i]));}sort(s,s+n+1);cout<<fixed<<setprecision(2)<<s[0];}問題 B: match
題目描述
小 x 在解說 F7 決賽時的搭檔是韓喬生,以至于小 x 沒有任何能說上話的機會。無聊的他玩起了填字游戲。一個 3*3 的九宮格里,每個格子里都被填上了一個字母,從而我們得到了 6 個單詞。現在,小 x 隨手寫了 6 個單詞,他想讓你幫他找到一種填字母的方案,使得這 6 個單詞都出現在了九宮格里。
輸入
共六行,每行一個長度為 3 的單詞(全部大寫)。
輸出
如果找不到方案,輸出“0”(不包含引號)
如果能找到,輸出包含 3 行,第 i 行對應九宮格的第 i 行(最后一行行末要換行)。
如果有多種方案,請輸出每種方案對應的字符串中字典序最前的一種(將行與行首尾相連,就可以得到一個字符串)。
樣例輸入 Copy
ANA
ANA
DAR
DAR
RAD
RAD
樣例輸出 Copy
DAR
ANA
RAD
思路:枚舉每一種方案,并判斷是否存在,如果存在就放到set中,然后輸出第一個字符串就是我們的答案(輸出的時候按照三行輸出就行
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") # include<bits/stdc++.h> # include<unordered_map># define eps 1e-9 # define fi first # define se second # define ll long long # define int ll // cout<<fixed<<setprecision(n) //bool operator<(const Node& x ) using namespace std; typedef unsigned long long ull; typedef pair<int,int > PII; const int mod=100000007; const int N=2e6+10; const int Time=86400; const int X=131; const int inf=0x3f3f3f3f; const double PI = 1e-4; double pai = 3.14159265358979323846; double e = exp(1);int T,n,m,k,d,ans,maxn; int f[1005][1005]; int a[N],b[N];string s[10]; int st[6]={0,1,2,3,4,5}; set<string>q; void solve(){for(int i = 0 ; i < 6 ; i ++ ) cin >> s[i];do{string res = "";res += s[st[0]];res+=s[st[1]];res+=s[st[2]];if(res[0] != s[st[3]][0] || res[3] != s[st[3]][1] || res[6] != s[st[3]][2]) continue;if(res[1] != s[st[4]][0] || res[4] != s[st[4]][1] || res[7] != s[st[4]][2]) continue;if(res[2] != s[st[5]][0] || res[5] != s[st[5]][1] || res[8] != s[st[5]][2]) continue;q.insert(res);}while(next_permutation(st,st+6));if(q.size() == 0) cout<<"0\n";else {string x;for(auto i : q){x = i ; break;}for(int i = 0 ; i < 9 ; i ++ ){cout<<x[i];if((i+1)%3 == 0) cout<<"\n";}} } /**/ signed main(){ std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); // cin >> T;T = 1;while(T--){solve();} return 0; }問題 C: 【動態規劃】cirs
題目描述
Czyzoiers 都想知道小 x 為什么對雞蛋餅情有獨鐘。經過一番逼問,小 x 道出了實情:因為他喜歡圓。最近小 x 又發現了一個關于圓的有趣的問題:在圓上有2N 個不同的點,小 x 想用 N 條線段把這些點連接起來(每個點只能連一條線段),使所有的線段都不想交,他想知道這樣的連接方案有多少種?
輸入
有且僅有一個正整數 N(N≤3000)。
輸出
要求的方案數(結果 mod 100000007)。
樣例輸入 Copy
2
樣例輸出 Copy
2
假如我們在圓上畫了2n個點,順時針編號為1,2,3,4……,你便會發現,如果一個奇數點和另一個奇數點相連,一定會造成將剩下所沒有連線的點分在兩邊的都是奇數個,而后兩邊必定有一個點沒線連或穿越其中的一條線,那么就不可能完成了。那么我們可以把奇數點看成左括號,偶數點看成右括號,然后把圓切開,就變成了一個括號匹配的方案數問題。為什么圓可以切開呢?因為A連B和B連A是同一種切法。
在這里可以用h(n)=C(2n,n)/(n+1),用擴展歐幾里德求逆元。
根據費馬小定理我們知道這樣的結論
固,我們可以結合卡特蘭數+逆元完成本題答案 這題很難啊為啥這么多人對了
問題 D: wtaxi
題目描述
話說小 x 有一次去參加比賽,雖然學校離比賽地點不太遠,但小 x 還是想坐出租車去。大學城的出租車總是比較另類,有“拼車”一說,也就是說,你一個人坐車去,還是一堆人一起,總共需要支付的錢是一樣的(每輛出租上除司機外最多坐下 4 個人)。剛好那天同校的一群 Oier 在校門口扎堆了,大家果斷決定拼車去賽場。
問題來了,一輛又一輛的出租車經過,但里面要么坐滿了乘客,要么只剩下一兩個座位,眾 Oier 都覺得坐上去太虧了,小 x 也是這么想的。
假設 N 位 Oier 準備拼車,此時為 0 時刻,從校門到目的地需要支付給出租車師傅 D 元(按車次算,不管里面坐了多少 Oier),假如 S 分鐘后恰能趕上比賽,那么 S 分鐘后經過校門口的出租車自然可以忽略不計了。現在給出在這 S 分鐘當中經過校門的所有的 K 輛出租車先后到達校門口的時間 Ti 及里面剩余的座位 Zi(1 <= Zi <= 4),Oier 可以選擇上車幾個人(不能超過),當然,也可以選擇上 0 個人,那就是不坐這輛車。
俗話說,時間就是金錢,這里小 x 把每個 Oier 在校門等待出租車的分鐘數等同于花了相同多的錢(例如小 x 等待了 20 分鐘,那相當于他額外花了 20 元錢)。
在保證所有 Oier 都能在比賽開始前到達比賽地點的情況下,聰明的你能計算出他們最少需要花多少元錢么?
輸入
每組數據以四個整數 N , K , D , S 開始,具體含義參見題目描述。
接著 K 行,表示第 i 輛出租車在第 Ti 分鐘到達校門,其空余的座位數為 Zi(時間按照先后順序)。
N <= 100,K <= 100,D <= 100,S <= 100,1 <= Zi <= 4,1<= T(i) <= T(i+1) <= S
輸出
對于每組測試數據,輸出占一行,如果他們所有人能在比賽前到達比賽地點,
則輸出一個整數,代表他們最少需要花的錢(單位:元),否則請輸出“impossible”。
樣例輸入 Copy
2 2 10 5
1 1
2 2
樣例輸出 Copy
14
思路:考慮dp,設f[i][j] : 第i輛車j個人的最少花費
因為題目說到時間的消費等價于金錢,那我們轉移的時候當然也要考慮多個人等待的時間拉。
轉移方程為f[i][[j] = min(f[i][j],f[i-1][j-z]+d+a*z) z∈[0,b];
問題 E: 聽歌識曲
題目描述
洛洛有一份私人歌單,歌單里面塞滿了他喜歡的歌曲,像夏戀、雨道、彩月、幻晝……整整有好幾百首。洛洛每天都要把他的歌單聽一遍,以致于他都能知道在什么時候放的是什么歌。
洛洛在向你推薦了他的歌單之后,決定考考你,從他的歌單開始播放起,第 t 秒正在播放的是第幾首歌。
輸入
第一行輸入兩個整數 n 和 t,分別表示歌單的歌曲總數以及第 t 秒播放哪首歌。
第二行有 n 個整數,A1, A2,…, An,分別表示歌單的第 i 首歌將會播放多長時間。
輸出
輸出一個整數,表示歌單按順序播放后,第t秒播放的是第幾首歌。
樣例輸入 Copy
樣例輸入1
3 5
5 5 5
樣例輸入2
3 5
1 4 5
樣例輸入3
3 5
1 3 5
樣例輸出 Copy
樣例輸出1
1
樣例輸出2
2
樣例輸出3
3
【樣例3解釋】
歌單中總共有三首歌:
第一首歌播放1秒,占第1秒;
第二首歌播放3秒,占第2-4秒;
第三首歌播放5秒,占第5-9秒。
所以第5秒播放的是第三首歌曲。
對于30%的數據,保證1≤n≤3;
對于60%的數據,保證1≤n≤2000,1≤Ai≤500;
對于100%的數據,保證1≤n≤100000,1≤Ai≤1000,1≤t≤
。
簽到題
#include<iostream> using namespace std; int a[100001]; int main() {long long n,t;cin>>n>>t;for(int i=1;i<=n;i++){cin>>a[i];if(t-a[i]<=0){cout<<i;break;}else{t-=a[i];}}}問題 F: 多面骰子
題目描述
洛洛現在手上有三顆多面骰子,多面骰子不是常見的六面骰子,而是33面骰子、100面骰子……一般來說,i面骰子每個面上的點數分別是1,2,3,……i。
洛洛手上的三顆骰子的面數可能并不相同,他想知道擲出三顆骰子的所有情況中,三顆骰子的點數之和出現最多次數是幾點。
如果存在多個點數之和出現次數相同的情況,則按點數之和從小到大順序輸出。
輸入
第一行輸入三個整數 n1, n2, n3,分別表示三顆骰子各自的面數。
輸出
輸出一行含任意個整數,分別表示次數最多的點數之和,用空格隔開。
樣例輸入 Copy
樣例輸入1
1 2 3
樣例輸入2
2 3 4
樣例輸出 Copy
樣例輸出1
4 5
樣例輸出2
6
提示
【樣例解釋】
樣例1,骰子投出來有以下六種情況:
1+1+1=3 1+1+2=4 1+1+3=5
1+2+1=4 1+2+2=5 1+2+3=6
可以看出4和5的出現次數最多且都是2次。
對于50%的數據,保證1 ≤ n1,n2,n3 ≤ 5;
對于80%的數據,保證1 ≤ n1,n2,n3 ≤ 10。
對于100%的數據,保證1 ≤ n1,n2,n3 ≤ 100。
思路:因為范圍再100以內所以可以n^3暴力直接做
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") # include<bits/stdc++.h> # include<unordered_map># define eps 1e-9 # define fi first # define se second # define ll long long # define int ll // cout<<fixed<<setprecision(n) //bool operator<(const Node& x ) using namespace std; typedef unsigned long long ull; typedef pair<int,int > PII; const int mod=1000000007; const int N=2e6+10; const int Time=86400; const int X=131; const int inf=0x3f3f3f3f; const double PI = 1e-4; double pai = 3.14159265358979323846; double e = exp(1);int T,n,m,k,ans,maxn; map<int,int>mp; void solve(){int n1,n2,n3;cin >> n1 >> n2 >> n3;for(int i = 1 ; i <= n1 ; i ++ )for(int j = 1 ; j <= n2 ; j ++ )for(int k = 1 ; k <= n3 ; k ++ ){mp[i+j+k]++;if(mp[i+j+k] > maxn){maxn = mp[i+j+k];ans = i + j + k;}}for(auto i : mp) if(i.second == maxn) cout<<i.first<<" ";}/* */ signed main(){ std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); // cin >> T;T = 1;while(T--){solve();} return 0; }問題 G: 花壇
題目描述
洛洛在散步的時候,看到公園的正方形花壇里開放著許多他不認識的花卉。仔細觀察之后,他又發現這些花的種植位置是有規律的。
洛洛發現在正方形花壇的最外層,即第一層上的花都是同一顏色;而花壇的第二層,花的顏色又都是一樣的……正方形花壇由若干層花構成,同一層上的花都是同一顏色的,不同層之間的花顏色不一定相同。如下圖所示,是一個具有三層花的正方形花壇:
在回到家后,洛洛還記得花壇有幾層花圍成,以及每層花的顏色,花的顏色用英文大小寫字母來表示。但是洛洛忘記了整個花壇的圖像,洛洛希望你根據他的描述,把整個花壇的圖像用計算機打印字符的方式表示出來。
輸入
第一行輸入一個整數 n,表示正方形花壇有n層花。
第二行輸入n個字符,第i個字符表示第i層花的顏色。第一層是花壇最外層。第n層是花壇最內層,只有一朵花。
輸出
輸出2n-1行,由(2n-1)(2n-1)個字符組成的花壇的圖像。
樣例輸入 Copy
樣例輸入1
3
abC
樣例輸入2
4
abac
樣例輸出 Copy
樣例輸出1
aaaaa
abbba
abCba
abbba
aaaaa
樣例輸出2
aaaaaaa
abbbbba
abaaaba
abacaba
abaaaba
abbbbba
aaaaaaa
提示
樣例解釋】
樣例1,即如上圖,只有三層花:
第一層是顏色為字符a的花,在最外層;
第二層是顏色為字符b的花,在第二層。
第三層是顏色為字符c的花,只有一朵,在最內層。
對于20%的數據,保證只有一種花,顏色為字符a;
對于50%的數據,保證1 ≤ n ≤ 10,顏色只用小寫字母表示,
對于80%的數據,保證1 ≤ n ≤ 100。
對于100%的數據,保證1 ≤ n ≤ 1000,顏色用小寫字母、大寫字母表示。
注意:對于不同層的花朵來說,可能存在顏色相同的情況。
思路:很簡單的一道模擬題,發現每個字母就正好賦值一圈,可以很容易得出一個結論就是如果有n個字母,那輸出的就是一個2n-1行和2n-1列的矩陣。
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") # include<bits/stdc++.h> # include<unordered_map># define eps 1e-9 # define fi first # define se second # define ll long long # define int ll // cout<<fixed<<setprecision(n) //bool operator<(const Node& x ) using namespace std; typedef unsigned long long ull; typedef pair<int,int > PII; const int mod=1000000007; const int N=2e6+10; const int Time=86400; const int X=131; const int inf=0x3f3f3f3f; const double PI = 1e-4; double pai = 3.14159265358979323846; double e = exp(1);int T,n,m,k,ans,maxn; string s; char a[2005][2005]; void solve(){cin >> n >> s;k = 2 * n - 1;for(int j = 0 ; j < n ; j ++ ){for(int i = j ; i < k ; i ++ ) a[j][i] = a[i][k-1] = a[k-1][i] = a[i][j] = s[j];k--;}for(int i = 0 ; i < 2 * n - 1 ; i ++){for(int j = 0 ; j < 2 * n - 1 ; j ++ )cout<<a[i][j];cout<<"\n";}}/* */ signed main(){ std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); // cin >> T;T = 1;while(T--){solve();} return 0; }問題 H: 排隊
題目描述
洛洛在外出旅游的時候發現社會上文明的現象越來越多,人們在買票的時候都會自發地排隊等候。
遺憾的是排隊的人身高參差不齊,有時候前后兩人之間的身高相差太大,缺乏一些美感。
如果把前后兩人的身高差(差值為正數)表示為兩者前后相鄰時產生的違和度,一段連續的人群因為前后兩人身高不同而產生的違和度之和就可以被稱為違和值。洛洛希望知道在隊伍哪一段,且該段隊伍由連續的m個人組成,其違和值最小。
輸入
第一行輸入兩個正整數 n,m,n表示隊伍的總人數,m表示某一段的人數。
第二行輸入n個整數,表示隊伍中n個人的身高(單位:厘米)。
輸出
輸出包含一個整數,即最小的違和值。
樣例輸入 Copy
樣例輸入1
4 3
1 2 4 7
樣例輸入2
4 3
10 7 5 4
樣例輸出 Copy
樣例輸出1
3
樣例輸出2
3
提示
樣例2說明:m=3,要選取3個連續的人有兩種選法:
10 7 5: 違和度之和=3+2=5
7 5 4: 違和度之和=2+1=3
所以答案是3。
對于50%的數據保證2 ≤ n ≤ 10;
對于80%的數據保證2 ≤ n ≤ 1000;
對于100%的數據保證2 ≤ n ≤ 100000,1 ≤ m < n,每個人的身高不超過300厘米。
思路:考慮差分
#include<iostream> #include<algorithm> using namespace std; int a[1000001],b[1000001],s[1000001]; int main() {int n,m,mi=999999999;cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];};b[1]=a[1];for(int i=2;i<=n;i++){b[i]=abs(a[i]-a[i-1]);}s[1]=0; for(int i=2;i<=n;i++) {s[i]=b[i]+s[i-1]; } for(int i=m;i<=n;i++) {mi=min(mi,s[i]-s[i-m+1]); } cout<<mi;}問題 I: 最大回文數
題目描述
回文數指的是一個數字,從左到右讀和從右到左讀都一樣。例如,1221和1234321是回文數,1234不是回文數。現有n個正整數ai(i=0,1,2,3,…n-1),請找出其中最大的回文數。
輸入
第一行只有一個正整數n,代表正整數ai的個數。
接下來的n行,每行包含一個正整數ai。輸入保證一定有回文數。
輸出
一行,一個正整數,即最大的回文數。
樣例輸入 Copy
【樣例1】
3
4718
1221
121
【樣例2】
5
3944
953
8
75739
46
樣例輸出 Copy
【樣例1】
1221
【樣例2】
8
提示
對于30%的數據,1≤n≤100,1≤ai≤108。
對于60%的數據,1≤n≤1000,1≤ai≤1016。
對于100%的數據,1≤n≤104,1≤ai≤1032。
思路:暴力判斷就行,復雜度O(n)
#include<iostream> #include<algorithm> using namespace std; string e[100001]; bool cmp(string a,string b) {if(a.size() ==b.size() )return a<b;elsereturn a.size() <b.size() ; } int main() { long long n,mm=-1; cin>>n; int k=0; while(n--) { string a,b;cin>>a;b=a;reverse(b.begin() ,b.end() );if(a==b){e[k++]=a;} } sort(e,e+k,cmp); cout<<e[k -1]; }問題 J: 金幣
題目描述
喬治在夢中來到了一個神奇部落,這個部落的神樹具有奇特的功能:對于每一位新朋友,都會獲贈金幣,而且金幣的數量會隨時間的延續而增加:
第1周,每天1枚金幣;
第2周,每天2枚金幣;
第3周,每天3枚金幣;……
請問:至少多少天,喬治的金幣數量達到n枚?
輸入
一行,只有一個正整數n。
輸出
一行,一個整數,表示金幣達到n枚所需的最少天數。
樣例輸入 Copy
30
樣例輸出 Copy
17
提示
第1周:每天1枚,共7枚;
第2周:每天2枚,共14枚;
第3周:每天3枚,3天即可:7+14+3*3=30。
共計:7+7+3=17天。
【數據規模】
對于30%的數據,n不超過2147483647;
對于100%的數據,n的位數不超過18。
思路:二分在第幾周,然后在精確判斷是第X天,復雜度是O(logn)
注意二分時取右邊界不要太大,自己粗略估計一下就行,取太大爆long long的。
別問我二分是啥或者代碼里面二分什么意思,看得懂的自然看得懂,看不懂我講了你也聽不懂,看不懂建議立刻去學,很簡單的
總結:這場除了C是個卡特蘭數其他題目都是中等難度,還行0.0
總結
以上是生活随笔為你收集整理的2021级新生个人训练赛第38场的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英特尔OpenVINO使用入门(C++集
- 下一篇: Monkey框架(测试方法篇) - mo