電信學院第一屆新生程式設計競賽題解及std
首先非常感謝各位同學的參加,還有出題驗題同學的辛勤付出
昨天想偷懶就是不想再把我C++11的想法改沒了,大家看不懂的可以百度一下哦,懶得再寫gcc了,畢竟程式碼是通的
題目型別一覽
A Kannyi的數字密碼 (模擬&&複雜的迴圈||手算)
B Kannyi愛乾淨(注意變數初始化||set)
C Kannyi的正方體和圓柱體(輸入輸出簽到,PI已提示)
D kannyi的獨木橋(max和min)
E Kannyi的簡單檢查 (迴圈簽到 注意'-')
F Kannyi的倒計時(a+b簽到)
G kannyi的開礦規劃(大力模擬)
H Kannyi的闖關遊戲(BFS 兩次最短路)
I Kannyi愛種樹(線段相交)
J Kannyi 的easy problem((數學||瞎猜)&&長整型)
K Kannyi的復旦(二分||stl)
5619: Kannyi的數字密碼
時間限制(普通/Java):1000MS/3000MS 記憶體限制:65536KByte總提交: 80 測試通過:30
描述
今天Kannyi說他要生成一些他的密碼,他會選擇Smith數作為他不同賬號的密碼。
Smith數是這樣定義的:一個數的各位之和等於其所分解的素因子各位數字之和。例如378就是Smith數,因為378=2×3×3×3×7,而且3+7+8=2+3+3+3+7。在這個定義中,這些素因子也要拆成各位數字再求和,例如22=2*11,且2+2=2+1+1,所以22也是Smith數。現在要去掉質數,並將剩下的數重新命名為kannyi數。
現在給你一個a,請輸出第a個Kannyi數。
輸入
輸入資料包含多組測試例項,每個測試例項佔一行,為一個正整數a (1 ≤ a ≤ 30)。
輸出
每個測試樣例佔一行,為第a個Kannyi數。
樣例輸入
3
樣例輸出
27
提示
OJ的評測機為windows,如需使用長整數(long long或__int64),輸入輸出請使用%I64d,本次比賽不再提示。
這個題目應該還好吧,滿足要求的數非常之少,甚至可以手算出來
當然你也可以去寫這個迴圈,數位之和就是個進位制轉換
#include<bits/stdc++.h> using namespace std; int sum_of_digit(int n) { int sum=0; while(n)sum+=n%10,n/=10; return sum; } int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int n; while(cin>>n) { int num=0; for(int i=0;;i++) { int sum=sum_of_digit(i),t=i; for(int j=2;j<i;j++) { if(t%j==0) { while(t%j==0) { sum-=sum_of_digit(j); t/=j; } } } if(t==i||i==2)continue; if(sum==0)num++; if(num==n) { cout<<i<<"\n"; break; } } } }
直接交表的程式碼(確實不太能手算,我錯了
#include<bits/stdc++.h> using namespace std; int num[]= {0, 4, 22, 27, 58, 85, 94, 121, 166, 202, 265, 274, 319, 346, 355, 378, 382, 391, 438, 454, 483, 517, 526, 535, 562, 576, 588, 627, 634, 636, 645, 648, 654, 663, 666, 690, 706, 728, 729, 762, 778, 825, 852, 861, 895, 913, 915, 922, 958, 985, 1086, 1111, 1165}; int main() { int a; while(~scanf("%d",&a)) { printf("%d\n",num[a]); } return 0; }
5618: Kannyi愛乾淨
時間限制(普通/Java):1000MS/3000MS 記憶體限制:65536KByte總提交: 272 測試通過:91
描述
Kannyi是一個非常愛乾淨的男孩子,他喜歡把自己東西都歸回原位。
今天,Kannyi面對了一個問題,他要把他的襪子放進衣櫃裡。Kannyi的收納包裡有n雙已經標過編號的襪子(每雙襪子一對相同編號,從1到n),現在襪子亂了,他想把它們成雙放進衣櫃裡。他會隨機從他的包裡拿出來一隻襪子,與此同時他尋找著桌上有沒有一隻襪子可以和拿出來的襪子配對。如果可以,他就會把它們一起放進衣櫃裡,否則他就把這隻襪子放在桌子上。就這樣,他把所有的襪子都整齊地放進了衣櫃裡。
現在Kannyi給你了他從收納包取襪子的號碼序列,請你告訴他桌子上出現過的最多襪子只數。
輸入
輸入資料包含多組測試例項,每個測試例項佔兩行。
第一行一個數n,表示Kannyi的襪子雙數(1≤n≤10)。
第二行一共2n個整數,表示了Kannyi從收納包依次取得的襪子號碼a1,a2,...,a2n(1≤ai≤n)。
輸出
每組樣例輸出收拾過程中桌子上出現過的最多襪子只數。
樣例輸入
1
1 1
3
2 1 1 3 2 3
樣例輸出
1
2
這個題目就是照抄Codeforces的A,但是原題要用hash方法,你們暫時沒有學就標記變數就好啦
#include <bits/stdc++.h> using namespace std; int main() { int n; while(cin>>n) { int a[15]={0},ma=0; for(int i=0,x; i<2*n; i++) { cin>>x; a[x]++; int f=0; for(int i=1;i<=n;i++) if(a[i]==1)f++; ma=max(ma,f); } cout<<ma<<"\n"; } return 0; }
如果用set那就比較簡單了
#include <bits/stdc++.h> using namespace std; int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int n; while(cin>>n) { n*=2; set<int>S; int ma=0; for(int i=0,x; i<n; i++) { scanf("%d",&x); if(S.count(x))S.erase(x); else S.insert(x); ma=max((int)S.size(),ma); } cout<<ma<<"\n"; } return 0; }
5620: Kannyi的正方體和圓柱體
時間限制(普通/Java):1000MS/3000MS 記憶體限制:65536KByte總提交: 447 測試通過:175
描述
簽到是不可能簽到的,這輩子都不可能不簽到的。
Kannyi現在有一個正方體和一個圓柱體,且兩個是等高的,並且側面積是相等。Kannyi很快知道了正方體的邊長a,請聰明的你告訴他圓柱體的體積。
輸入
輸入資料包含多個測試例項,每個測試例項佔一行,為一整數a(1 ≤ a ≤ 102)
輸出
每行輸出為圓柱體的體積V,保留1位小數。
樣例輸入
1
樣例輸出
1.3
提示
PI=acos(-1)
這個純粹就是偷懶題,直接從高考卷拿了個選擇題,不過高考卷是讓求兩者的比例的
相信同學們都能解出來正方體V:圓柱V=PI:4,好心提示了一波PI的較為精確值
#include<bits/stdc++.h> using namespace std; const double PI=acos(-1); int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int n; while(cin>>n)printf("%.1f\n",n*n*n*4/PI); }
當然你也可以這樣,這個題目並不卡精度
#include<bits/stdc++.h> #define PI acos(-1) using namespace std; int main() { int a; while(cin>>a) { double sc=a*a*4.0; double d=sc*1.0/a; double r=d/2.0/PI; double v=r*r*PI*a; printf("%.1f\n",v); } return 0; }
5627: kannyi的獨木橋
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 24 Accepted:9
Description
kannyi的女神小M經常對kannyi說,你走你的獨木橋(劃重點),我走我的陽關道。kannyi不以為然,卻對獨木橋產生了濃厚的興趣,併產生了一個問題:
獨木橋的長度為m(1~m自西向東),每個人都有初始位置和初始方向,每個人每秒只能移動1個單位,當一個人到0或者m+1,則代表已經離開獨木橋。每個人都會朝一個方向行走,中途不會自己改變方向。要是兩人相遇,兩人會分別轉身繼續行走 ,轉身不需要時間。
現在kannyi想知道最早和最遲離開獨木橋的人的時間。
Input
多組輸入,第一行輸入整數n,m,分別代表獨木橋上的人數,橋的長度。(1<=n<=m<=1000000)
接下來n行,每行輸入兩個整數pi(1<=pi<=m)和di,分別代表第i個人的位置和朝向(di為-1時,朝向西,di為1時,朝向東),每個人的位置都不一樣。
保證輸入資料合法。
Output
輸出一行,兩個整數,分別為最早和最遲離開獨木橋的人的時間(秒)。兩個整數由一個空格符分開。
Sample Input
2 4
1 1
3 -1
Sample Output
3 4
Hint
樣例解釋:第一個人在1的位置,方向向東,第二個人在3的位置,方向向西,兩人在位置2相遇,然後分別轉向,第一個人離開獨木橋所用時間就是1->2,2->1,1->0,用時3秒;第二個人離開獨木橋所用時間就是3->2,2->3,3->4,4->5,用時4秒。
兩個人相遇,可以認為他們穿過了對方,比如一個人的初始位置是1,方向向東,2秒後一定有個人在3這個位置,雖然可能不是同一個人,把全部人看做一個整體,不管是不是同一個人,對結果並沒有影響,所以相遇就等價於穿過對方。
/*
我的口胡
但是題目保證資料合法了,問題就是相遇了怎麼辦,其實相遇了就是兩者的時間的互換,自己可以試一下,因為每個人都要走到目標點的
所以朝向東就是自己走或者相遇者走m+1-a,朝向西就是自己走或者相遇者走a,分別取大取小就是答案
*/
#include<bits/stdc++.h> using namespace std; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int minn=1e9,maxx=0; for(int i=0;i<n;i++) { int a,b; scanf("%d%d",&a,&b); minn=min(minn,b==1?m-a+1:a); maxx=max(maxx,b==1?m-a+1:a); } printf("%d %d\n",minn,maxx); } return 0; }
5621: Kannyi的簡單檢查
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 633 Accepted:149
Description
這裡是2018年電信學院第一屆新生程式設計競賽 ,當然要和1有關了。大家都非常喜歡數字1,不管在遊戲中還是現實中,都有個冠軍夢。IG niubi!
Kannyi現在給你一個數字a,讓你看看是否只含數字1,如果是請輸出讓人心動的"Accepted",不是請輸出令人心碎的"Wrong Answer"。
Input
輸入資料包含多個測試例項,每個測試例項佔一行,為整數a(-109≤ a ≤ 109)
Output
每個測試樣例輸出為1行,輸出"Accepted"或"Wrong Answer"。
Sample Input
1
10
1111
2333
Sample Output
Accepted
Wrong Answer
Accepted
Wrong Answer
注意負數就好了,簡單迴圈,當然你也可以進位制轉換
#include<bits/stdc++.h> using namespace std; int la(int x) { while(x) { if(abs(x%10)!=1)return 1; x/=10; } return 0; } int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int x; while(~scanf("%d",&x)) { if(la(x))printf("Wrong Answer\n"); else printf("Accepted\n"); } }
迴圈就完事的
#include<bits/stdc++.h> using namespace std; const double PI=acos(-1); int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); char s[15]; while(~scanf("%s",s)) { int f=0; for(int i=0; s[i]; i++) { if(s[i]=='-')continue; else if(s[i]!='1')f=1; } if(f)printf("Wrong Answer\n"); else printf("Accepted\n"); } }
5622: Kannyi的倒計時
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 310 Accepted:160
Description
本次新生賽在12-08舉辦,工作人員需要執行出題、借教室等各種各樣任務,但是這一群人有人有拖延症。
有句話怎麼講呢,deadline才是第一生產力,只要有某件事你看到需要迫切去做了,你就會去做。所以Kannyi要通過倒計時去刺激這些工作人員。
本次活動時間對於工作人員來說是11-12到12-10,所以請你算算給定工作時間距今天(12-08)有幾天,為了區分在比賽前還是比賽後,請加上"+"、"-"號以便區別。
Input
輸入資料包含多個測試例項,每個測試例項佔一行,為一日期,格式為: "MM-DD"。
Output
每行輸出為距離今天的天數x。
Sample Input
11-12
12-08
12-10
Sample Output
+26
0
-2
不要說沒給a+b簽到哦,算日期是典型的a+b(強行a+b
#include<bits/stdc++.h> using namespace std; int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int m,d; while(~scanf("%d-%d",&m,&d)) { int ans; if(m>11)ans=8-d; else ans=38-d; if(ans>0)printf("+"); printf("%d\n",ans); } }
5628: kannyi的開礦規劃
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 14 Accepted:1
Description
kannyi是某外星開礦公司的負責人,打算在某星球開礦。已知,這星球上的礦井都有對應的座標點。一切開礦作業都靠開礦bot而非人類完成,飛船上只有一個傳送門,請你思考一下在這顆星球上最多能獲利多少。
*對傳送門能做的所有操作:
1.啟動:啟動傳送門需要消耗E1的電力,不消耗時間。
2.關閉:關閉傳送門不消耗電力和時間。
3.修改:修改傳送門的目標,不消耗電力和時間。但在傳送門關閉的時候才能修改。修改的目標只能是每個礦井的入口處。
4.傳送:當傳送目標確定後並且傳送門開啟的時候,可以選擇將任意數量的開礦bot傳送到指定地點。這不消耗時間但是會消耗n*E2的電力(n為傳送的bot的數量),而將n個bot傳送回來消耗的電力也相同。
5.維持:只要傳送門啟動著,每過一個單位時間就需要消耗E3的電力。
*對bot能做的操作:
1.移動:無論是上移或是下移,bot都會消耗1電力和1單位時間(電力充足無須擔心)。從礦井入口下到地下單位一層也視作移動,從傳送門到礦井入口不視作移動。
2.開採&裝載:一個bot理論能承擔至多25單位的礦物,開採25單位礦物消耗1電力和2單位時間(開採操作預設會直接挖夠25礦物),無論攜帶多少礦物都不影響bot的移動速度和消耗電力。
3.等待:等待不消耗電力。
*雜項:
1.1電消耗1錢,1礦換1錢,不存在電費梯度和礦物過度導致市場飽和問題。
2.中途赤字不影響開工。
3.傳送門只有在指向某個座標的時候,這個座標的bot才能夠傳送回去。
4.消耗電力是每個bot單獨計算,而時間層面,各個bot行動可以同時進行。
5.第n層沒有挖掘不影響bot直接下到n層下面的移動動作。
Input
多組輸入,每組的第一行是一個正整數N(1<=N<=100),代表該星球上已經佈置了多少座標點,輸入以N=0結束。
然後是三個正整數E1,E2和E3(1<=E2,E3<E1<=50)。
接下來是N對正整數ti和hi,ti表示該傳送點下的礦井單位深度內有多少礦物,hi表示該礦井極限深度。(0<=ti<=500,ti%25=0,1<=hi<=10)。
Output
輸出最多盈利額。
Sample Input
Sample Output
Hint
開門後傳送5個bot過去,分別派遣到1-5層,挖掘結束後回到傳送門回來。
bot共消耗35電量,花費總時間12單位,傳送門則消耗15+1*12(等待)=27電量,實際獲取礦物125單位。
所以最終盈利為53。
這個題目看懂題意,模擬一下就好了(看不懂或者感覺卡就對了,但是絕對是能做的
等國泥老哥的std
5624: Kannyi的闖關遊戲
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 39 Accepted:15
Description
Kannyi最近迷上了一款通關的小遊戲,是魔塔的簡化版,現在繼續將這個簡化。
有一二維的影象,你可以在一個時間單位內進行上下左右移動,要通往下一關需要先去拿到鑰匙,再去門口,是有時間限制的。現在Kannyi把圖告訴你,希望你能告訴他最快可以在幾個時間單位內到達,如果不能到達請輸出"Oops! Something went wrong"(不包含引號)。
Input
題目包括多組測試資料。
每組測試資料以兩個整數n,m(0<n, m≤20)開頭,分別代表影象的長和高。緊接著有n行,m列字元,由".","#","S","K","E"組成。其中:
"." 代表能夠行走的空地。
"#" 代表牆壁,人物不能從此通過,除此之外均可以通過。
"S" 是人物初始所在的位置。
"K" 是鑰匙所在的位置。
"E" 是通往下一關的門的位置。
任務只能選擇上、下、左、右任意一方向走一步。
Output
每組輸出Kanny通過這一關的最短時間,如果不能達到輸出"Oops! Something went wrong"。
Sample Input
1 3
SEK
4 4
....
....
..K.
S##E
4 4
....
...K
.###
S##E
Sample Output
3
5
Oops! Something went wrong
emmm,只有bfs可以找到最短路,dfs還是不要費力氣了
#include<bits/stdc++.h> using namespace std; struct T { int x,y,f; }q[405]; int d[4][2]={1,0,-1,0,0,1,0,-1}; char s[25][25]; bool vis[25][25]; int n,m,kx,ky; int bfs(int x,int y) { memset(vis,0,sizeof vis); int tot=0,sum=1; q[0]={x,y,0}; vis[x][y]=1; while(tot<sum) { for(int i=0;i<4;i++) { int nx=q[tot].x+d[i][0],ny=q[tot].y+d[i][1]; if(nx==kx&&ny==ky)return q[tot].f+1; if(nx>=0&&ny>=0&&nx<n&&ny<m&&vis[nx][ny]==0&&s[nx][ny]!='#') vis[nx][ny]=1,q[sum++]={nx,ny,q[tot].f+1}; } ++tot; } return 1000; } int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); while(~scanf("%d%d",&n,&m)) { for(int i=0; i<n; i++)scanf("%s",s[i]); int sx,sy,ex,ey; for(int i=0; i<n; i++) for(int j=0; j<m; j++) { if(s[i][j]=='K')kx=i,ky=j; else if(s[i][j]=='S')sx=i,sy=j; else if(s[i][j]=='E')ex=i,ey=j; } int ans=bfs(sx,sy)+bfs(ex,ey); if(ans>1000)printf("Oops! Something went wrong\n"); else printf("%d\n",ans); } }
5625: Kannyi愛種樹
Time Limit(Common/Java):2000MS/6000MS Memory Limit:65536KByteTotal Submit: 258 Accepted:6
Description
在一堂有趣的C語言實驗課上,老師讓同學們做一道題叫校門外的樹,這時一個同學問我,這個題還有這麼一個思路,(以下省略AC答案)。我一聽,小夥子不錯,這想法很奇妙,為了滿足他的小需求(變態需求),我特地為他出了這麼一個題。
Kannyi是一個植樹隊的隊長,為了讓城市變得更美好,他決定在城市的馬路上種上樹,於是他向政府提出了申請,政府很快就通過了,並給了一些要求。政府要求Kannyi只允許在馬路一側種上樹,並給他劃出了一段總長為L米的馬路。政府還劃定了M段連續的區域需要種上樹。
Kannyi一看這麼多要求頭就大了,政府劃定的區域有長有短,有覆蓋還有包含,這讓他不知如何是好,愚蠢的他算了好幾天也沒算清楚到底要種幾棵樹,於是他找到了聰明的你,希望你能幫助他解決這個問題。
Input
第一行輸入一個T代表一共T組資料,每組資料輸入第一行包含兩個非負整數L和M,L代表馬路的總長度,M代表需要種樹的區域。接下來M行,每行有兩個數字a,b,代表區域[min(a,b),max(a,b)]需要種上樹。
資料保證:
T≈100
1<=L<=10^6
0<=M<=10^5
1<=a,b<=L
Output
輸出包含一行,表示Kannyi的植樹隊滿足政府的所有需求後到底需要在馬路上種多少顆樹。
Sample Input
2
10 4
4 4
3 7
1 3
2 5
5 0
Sample Output
7
0
Hint
樣例1:[1,7]被種上了樹,一共種了7棵樹。
樣例2:沒有地方被種上樹。
這個題目資料範圍非常之大,暴力標記什麼的都是不行的,我們要使用線段求交,實質就是解決三種問題
————————
————————
————————
———————
————————
————
然後就可以愉快做題了
我的程式碼,等一波他們簡單易懂的程式碼
#include<bits/stdc++.h> using namespace std; vector<pair<int,int> >V; int main() { int T; scanf("%d",&T); while(T--) { V.clear(); int n; scanf("%d%d",&n,&n); for(int i=0,x,y; i<n; i++)scanf("%d%d",&x,&y),V.push_back({min(x,y),max(x,y)}); sort(V.begin(),V.end()); int r=-1,s=0; for(auto X:V) { if(X.second<=r)continue; if(X.first>r) s+=X.second-X.first+1; else s+=X.second-r; r=X.second; } printf("%d\n",s); } }
5626: Kannyi 的easy problem
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 703 Accepted:103
Description
已知式子2n – 1,求該式子在1到n範圍內能被7整除的正整數n的個數有多少個?
Input
多組輸入,每組輸入只有一個n(0<n<=1e18),當n等於0時程式結束。
Output
輸出範圍內n的個數。
Sample Input
10
0
Sample Output
3
猜就完事,猜對了做不出來看看A的提示啊
這個題的證明可以這樣來,2^n-1之後就是一個全為1的2進位制數列
然後我進行求餘,發現三位就是一迴圈(其實這就是編譯原理的自動機
桃子的歸納法
#include<stdio.h> int main() { __int64 n; while(scanf("%I64d",&n),n)printf("%I64d\n",n/3); }
5629: Kannyi的復旦
Time Limit(Common/Java):3000MS/6000MS Memory Limit:80000KByteTotal Submit: 103 Accepted:11
Description
校園的天色逐漸暗了下來,教學樓裡的人們也匆匆散去。Kannyi為了實現他小小的名校夢想,孑身一人坐在學習室裡靜修。不知不覺之中,時間過了零點。Kannyi的女神小M見狀,便上前勸著Kannyi早些休息。然而Kannyi卻依然沉迷在自己的考研真題中,絲毫沒有睏意。
於是,小M給Kannyi出了一道難題,如果Kannyi答錯,就必須答應小M回去休息。但是Kannyi可不會輕易認輸,便答應了小M的挑戰:
小M給出了四個數列A,B,C,D,每個數列都包含著n個數。需要Kannyi從每個數列中各取出1個數,使4個數之和為0,並求出這樣的組合個數。當一個數列中有多個相同數字時,把它們作為不同的數字看待。
Kannyi真的很想考上覆旦大學^-^,所以他必須留下來繼續學習,你能幫一幫為夢想執著的Kannyi嘛>o<!
Input
第一行輸入n,表示各數列所含數字的個數。(1≤n≤4000)
接下來有4行,分別代表A,B,C,D數列,每行有n個數字。(|各數字的值|≤1000)
Output
符合條件的組合總數。
Sample Input
6
-45 -41 -36 -36 26 -32
22 -27 53 30 -38 -54
42 56 -37 -75 -10 -6
-16 30 77 -46 62 45
Sample Output
5
Hint
樣例中符合條件的5種組合如下:
{-45 -27 42 30}
{26 30 -10 -46}
{-32 22 56 -46}
{-32 30 -75 77}
{-32 -54 56 30}
二分或者用stl的hash unordered_map
等一波他們的程式碼