牛客小白月赛16练习
?
?
?
G-小石的圖形
鏈接:https://ac.nowcoder.com/acm/contest/949/G
來源:牛客網
題目描述
小石想在一面墻旁邊建造一段長度為?n 的籬笆來圍出一塊地(如圖)。求最大的地的面積。
輸入描述:
共一行,輸入一個整數 n 。輸出描述:
共一行,輸出最大面積,保留 3 位小數。示例1
輸入
1輸出
0.159備注:
0≤n≤103一看就是水題,上網搜了下π的取值,3.1415926535898,同學用的3.1415926wa掉了
發現半圓時面積最大(顯然)。?n=πR,R=n/π
面積S=πR2/2=n2/2π
?
?
E-小雨的矩陣
鏈接:https://ac.nowcoder.com/acm/contest/949/E
來源:牛客網
題目描述
小雨有一個 n×n?的矩陣,起點在(1,1),終點在(n,n),只能向下或向右走,且每次只能走 1 步。矩陣上每個點都有一個點權 ai,j。求走到終點的路徑有多少不同的點權和。
輸入描述:
第一行,輸入一個正整數 n 。接下來 n+1 行,每行 n 個數,表示 ai,j。
輸出描述:
共一行,輸出有多少不同的點權和。示例1
輸入
2 1 5 2 4輸出
2說明
(1,1)→(2,1)→(2,2):和為7。(1,1)→(1,2)→(2,2):和為10。備注:
1≤n≤8,0≤ai,j≤50剛開始以為很難,后來發現也就是一道水題,從(1,1)爆搜到(n,n),把答案去一下重即可。
用DFS,結果存到set中就好了
1 #include <stdio.h> 2 #include <string.h> 3 #include <set> 4 using namespace std; 5 6 int N[9][9]; 7 int T[2][2]={{0,1},{1,0}}; 8 int vis[9][9]; 9 int n; 10 11 set<int> st; 12 13 void DFS(int x,int y,int sum) 14 { 15 16 if(x==n&&y==n) 17 { 18 st.insert(sum); 19 return; 20 } 21 for(int i=0;i<2;i++) 22 { 23 int a=x+T[i][0]; 24 int b=y+T[i][1]; 25 if(a<1||b<1||a>n||b>n) 26 continue; 27 if(!vis[a][b]) 28 { 29 vis[a][b]=1; 30 DFS(a,b,sum+N[a][b]); 31 vis[a][b]=0; 32 } 33 } 34 return; 35 } 36 37 int main() 38 { 39 scanf("%d",&n); 40 for(int i=1;i<=n;i++) 41 { 42 for(int j=1;j<=n;j++) 43 { 44 scanf("%d",&N[i][j]); 45 } 46 } 47 DFS(1,1,N[1][1]); 48 printf("%d",st.size()); 49 return 0; 50 }?
?
A-小石的簽到題
鏈接:https://ac.nowcoder.com/acm/contest/949/A
來源:牛客網
題目描述
小石和小陽玩游戲,一共有?n個數,分別為?1~n。兩人輪流取數,小石先手。對于每輪取數,都必須選擇剩下數中的任意一個數 x,同時還要取走?x,?x/2?,??x/2?/2?……?如果某個數不存在,就停止取數(不能一個數都不取)。誰取走最后一個數,誰就輸了。小石想知道自己能否獲勝。 如果小石能贏,輸出?“Shi”,否則輸出?"Yang”(均不輸出引號)。
輸入描述:
共一行,輸入一個數?n。輸出描述:
共一行,輸出 "Shi" 或 "Yang"(不輸出引號)。示例1
輸入
1輸出
Yang說明
小石只能取走 11,小陽贏。示例2
輸入
2輸出
Shi說明
若小石取走 11,則小陽只能取走 22,小石贏。備注:
1≤n≤109?
第一題看到別人幾分鐘就做出來了,很是懵逼,想不出為什么呀。。。估計可能是規律題,要猜猜
第一次是猜奇數小陽贏,偶數小石贏,錯了。
后來發現當 n>1 時先手(小石)總是贏。如何證明:一開始有 1~n?, n?個數,假設先手必敗,那么先手選 1,后手就進入了必敗狀態。所以假設錯誤,那么先手就不是必敗,先手一定有一種方式能贏。
?怪不得有人四十多秒就做出來。。
1 #include<stdio.h> 2 3 int main() 4 { 5 int n; 6 scanf("%d",&n); 7 if(n==1) 8 printf("Yang\n"); 9 else 10 printf("Shi\n"); 11 return 0; 12 }?
?
C-小石的海島之旅
鏈接:https://ac.nowcoder.com/acm/contest/949/C
來源:牛客網
題目描述
暑假到了,小石和小雨到海島上玩。從水平方向看海島可以看成 n個小塊,每一個小塊都有一個高度hi,
水位一開始為 0,隨著水位的上升,海島分成了若干塊。
現在有 m?個詢問,求當水位為ai?時,海島會分成多少塊。
輸入描述:
第一行輸入兩個正整數n,m,分別表示海島小塊個數和詢問個數。第二行輸入 n 個整數 hi,表示每一塊的高度。
第三行輸入 m個整數 ai,表示每一個詢問,保證輸入的 ai 單調遞增。
輸出描述:
共?m 行,分別對應?m 個詢問的答案。示例1
輸入
7 3 1 2 3 1 2 1 3 1 2 3輸出
3 2 0說明
當水位高度為 1 時,島嶼被分成 3 塊,2 3;2;3當水位高度為 2 時,島嶼被分成 2 塊:3;3 。
當水位高度為 3 時,島嶼全部被淹沒,剩余 0 塊 。
備注:
1≤n,m≤103,1≤hi≤109,1≤ai<ai+1≤109我們按海島的高度 hi 從大到小排序。
假設海島i在水位為 ai 時被淹沒,如果海島 i?1 和海島 i+1 都已被淹沒,那么就少了一塊,答案減 1 。
如果海島 i?1 和海島 i+1 都沒被淹沒,那么一塊變兩塊,答案加 1 。
否則答案不變。
由于出題人良心,直接N2是能過的。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <queue> 8 using namespace std; 9 #define maxn 1002 10 int D[maxn]; 11 int F[maxn]; 12 int main() 13 { 14 //freopen("sample.txt","r",stdin); 15 int n,m; 16 scanf("%d %d",&n,&m); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&D[i]); 20 } 21 memset(F,1,sizeof(F)); 22 F[n+1]=0; 23 for(int i=0;i<m;i++) 24 { 25 int t; 26 scanf("%d",&t); 27 for(int j=1;j<=n;j++) 28 { 29 if(F[j]&&D[j]<=t) 30 { 31 F[j]=0; 32 } 33 } 34 int tot=0; 35 for(int j=1;j<=n;j++) 36 { 37 if(F[j]&&!F[j+1]) 38 { 39 tot++; 40 } 41 } 42 printf("%d\n",tot); 43 } 44 return 0; 45 }
?
?
?
B-小雨的三角形
鏈接:https://ac.nowcoder.com/acm/contest/949/B來源:牛客網
題目描述
小雨手上有一個填滿了數字的三角形。這個三角形一共有?n?層,其中第?i?層共有?i個數,且第?1?個數和第?i?個數均為?i?。其余的數中,第?j?個數是上一層中第?j?1?個數和第?j?個數的和。小雨想知道這個三角形第?x?層到第?y?層所有數的和,一共有?m?個詢問。
輸入描述:
第一行兩個正整數 n,m,表示這個三角形的層數和詢問個數。接下來?m 行,每行兩個正整數 x,y,表示一次詢問。
輸出描述:
輸出共?m 行,每行一個整數,表示一組詢問的答案,對?109+7 取模。示例1
輸入
5 3 1 2 1 5 3 5輸出
5 83 78說明
畫出這個三角形:1
2 2
3 4 3
4 7 7 4
5 11 14 11 5
第?1~2 層的和為?1+2+2=5 。
第?1~5 層的和為?1+2+2+3+4+3+4+7+7+4+5+11+14+11+5=83 。
第?3~5 層的和為 3+4+3+4+7+7+4+5+11+14+11+5=78?。
備注:
1≤n≤103,1≤m≤103,1≤x≤y≤n神坑題,錯了好多次,做題不規范,賽后兩行淚,注意,數據可能會溢出,而且要優化算法,減少算法復雜度,防止時間超限和數據溢出導致的wa
數據范圍給的很小,可以 O(n2) 暴力構造三角形,預處理出每一行的總和,每個詢問把 x~y 行的和加起來即可(若預處理出第 1~i 行的和,則可以做到 O(1) 查詢)。
更快的做法?每一行的和其實是有規律的,分別為 1,4,10,22,46,94??,除了第 11 行的和為 11 外,第 ii行的和為 6?2i?2?2,那么第 1~i?(i>1)行的和為
所以第 x~y?行的和就能用前綴和計算了,注意特判 x=1,x=2,y=1?的情況,這樣就能夠每次 O(log?n) 查詢。
?
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <queue> 8 using namespace std; 9 #define maxn 1001 10 long long dp[maxn]; 11 12 int main() 13 { 14 //freopen("sample.txt","r",stdin); 15 int n,m; 16 scanf("%d %d",&n,&m); 17 dp[1]=1; 18 for(int i=2;i<=n;i++) 19 { 20 dp[i]=(dp[i-1]*2+2)%(long long)(pow(10,9)+7); 21 } 22 for(int i=0;i<m;i++) 23 { 24 int a,b; 25 scanf("%d %d",&a,&b); 26 long long sum=0; 27 for(int g=a;g<=b;g++) 28 { 29 sum=(sum+dp[g])%(long long)(pow(10,9)+7); 30 } 31 printf("%lld\n",sum); 32 } 33 return 0; 34 }?
D-小陽買水果
鏈接:https://ac.nowcoder.com/acm/contest/949/D
來源:牛客網
題目描述
水果店里有 n個水果排成一列。店長要求顧客只能買一段連續的水果。小陽對每個水果都有一個喜愛程度 ai,最終的滿意度為他買到的水果的喜歡程度之和。
如果和為正(不管是正多少,只要大于 0 即可),他就滿意了。
小陽想知道在他滿意的條件下最多能買多少個水果。 你能幫幫他嗎?
輸入描述:
第一行輸入一個正整數 n,表示水果總數。第二行輸入 n 個整數 ai,表示小陽對每個水果的喜愛程度。
輸出描述:
一行一個整數表示結果。(如果 1 個水果都買不了,請輸出 0)示例1
輸入
5 0 0 -7 -6 1輸出
1備注:
1≤n≤2×106,|ai|≤103?
想法:i從1到n遍歷時,就先求出1到i的和,然后在此sum后,只要有一個sum值比它大,就說明它倆中間的數的和為正數,此時的位置之差就是此刻連續的長度,跟max比較就好了
但數據不允許,要對算法做優化。
?
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define maxn 2000005 5 using namespace std; 6 int sum[maxn],maxx[maxn]; 7 int ans=0; 8 int main() 9 { 10 int n; 11 scanf("%d",&n); 12 memset(maxx,-0x3f3f3f,sizeof(maxx)); 13 for(int i=1;i<=n;i++) 14 { 15 scanf("%d",&sum[i]); 16 sum[i]+=sum[i-1]; 17 } 18 for(int i=n;i>=1;i--) 19 maxx[i]=max(sum[i],maxx[i+1]); 20 for(int l=1,r=1;l<=n&&r<=n;l++,r++) 21 { 22 if(maxx[r]<=sum[l-1]) continue; 23 else while(maxx[r]>sum[l-1]){ 24 r++; 25 } 26 ans=max(ans,r-l); 27 } 28 printf("%d",ans); 29 }?
?
?
?
?
1 #include<bits/stdc++.h> 2 #define rep(X,A,B) for(int X=A;X<=B;X++) 3 #define tep(X,A,B) for(int X=A;X>=B;X--) 4 #define LL long long 5 #define ls son[x][0] 6 #define rs son[x][1] 7 const int N=2000010; 8 const int MOD=1e9+7; 9 using namespace std; 10 11 int n; 12 13 struct nn{ 14 int num,pos; 15 }a[N]; 16 17 int cmp(nn A,nn B){ 18 if(A.num==B.num)return A.pos>B.pos; 19 return A.num<B.num; 20 } 21 22 int main(){ 23 scanf("%d",&n); 24 int x; 25 rep(i,1,n)scanf("%d",&x),a[i].num=a[i-1].num+x,a[i].pos=i; 26 n++;a[n].pos=a[n].num=0; 27 sort(a+1,a+n+1,cmp); 28 int las=n,ans=0; 29 rep(i,1,n){ 30 las=min(las,a[i].pos); 31 if(las<a[i].pos)ans=max(ans,a[i].pos-las); 32 } 33 printf("%d\n",ans); 34 return 0; 35 }?
?
?
?
題解地址
轉載于:https://www.cnblogs.com/jiamian/p/11179585.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的牛客小白月赛16练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Csharp: Treeview che
- 下一篇: 关于selectNodes与select