Wannafly挑战赛3
生活随笔
收集整理的這篇文章主要介紹了
Wannafly挑战赛3
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
給你一個長?n?的序列,m?次查詢
每次查詢給一個?x,然后:
從序列的最左端?1?開始,每次隨機的選擇一個右端點?r,如果兩個端點間的區間和不超過?x?,就進行一次分割,然后把左端點變成?r + 1, 否則一直隨機下去。
問這樣分割出來的期望段數
輸入描述:
第一行兩個數 n,m之后一行 n 個數表示這個序列
之后m行每行一個數 x,表示求每段的和不大于 x 的情況下切割的期望段數
輸出描述:
m 行,每行一個保留到小數點后2位的數表示答案如果無論如何都沒有合法的切割方案,輸出"YNOI is good OI!",不含引號 示例1
輸入
5 6 1 2 3 4 5 4 5 6 7 8 9輸出
YNOI is good OI! 4.25 3.83 3.58 3.58 3.11說明
對于30%的數據,n , m <= 10對于60%的數據,n <= 1000 , m <= 10
對于80%的數據,n <= 100000 , m <= 100
對于100%的數據,n <= 100000 , m <= 500 , 0 <= a[i] <= 1000 , x <= 1000000
看了好久才知道題意。。。
就是把n個數分段,要求每一段的區間和小于等于x,然后求一下期望段數 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=1e5+88; int a[N],sum[N],n,m,x; double dp[N],Sum[N]; int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;++i) {scanf("%d",a+i);sum[i]=a[i]+sum[i-1];}while(m--){bool ok=1;scanf("%d",&x);int pos=n;for(int i=n;i>=1;--i) {if(a[i]>x) {ok=0;break;}else {while(sum[i-1]+x<sum[pos]) --pos;double shu=pos-i+1;dp[i]=(Sum[i+1]-Sum[pos+2])/shu+1;}Sum[i]=Sum[i+1]+dp[i];}if(!ok) puts("YNOI is good OI!");else printf("%.2f\n",dp[1]);} }
題目描述
給一個數組{a},定義?h(a,b)為在十進制下?a + b?與?a?的位數差,求?,0的位數為1。?
?
輸入描述:
第一行讀入一個正整數 n (1 <= n <= 105)。
第二行讀入 n 個非負整數,第 i 個表示a[i] (0 <= a[i] <= 108)。
輸出描述:
一行表示答案。 示例1輸入
10 0 1 2 3 4 5 6 7 8 9輸出
20#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+88; int sum[N],n,a[N],san[N],b[N]; long long s[15]; void add(int p){for(;p<=n+55;p+=(p&(-p))) ++sum[p]; } int query(int p){int ans=0;for(;p;p-=(p&(-p))) ans+=sum[p];return ans; } int main(){long long ans=0;scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",a+i),b[i]=a[i];sort(b+1,b+n+1);b[0]=0;s[1]=0,s[2]=10;for(int i=3;i<=14;++i) s[i]=s[i-1]*10;for(int i=1;i<=n;++i) san[i]=lower_bound(b+1,b+n+1,a[i])-b;for(int i=n;i>=1;--i){int now=a[i],wei=0,cha;if(!now) wei=1;while(now){now/=10;++wei;}int ct=wei;while(1){++wei;cha=s[wei]-a[i];int xia=lower_bound(b+1,b+n+1,cha)-b-1;if(xia==n) break;ans+=query(n+1)-query(xia);}add(san[i]);}printf("%lld\n",ans); } 給定一個 n*m 的矩陣,矩陣元素由X和O構成,請求出其中最大的蝴蝶形狀。
蝴蝶形狀的定義如下:
存在一個中心點(必須為X),并且其往左上(必須為X)、左下(必須為X)、右上(必須為O)、右下(必須為O)四個方向擴展相同的長度,且左上頂點與左下頂點之間全由X填充,右上頂點與右下頂點之間全由O填充。
我們不在意在蝴蝶形狀內部是X還是O。 例如:
? ? XAAAO
? ? XXAOO
? ? XAXAO
? ? XXAOO
? ? XAAAO
是一個蝴蝶形狀(其中A表示X或O)。
? ? X
也是。
而
? ? XAAO
? ? XXOO
? ? XXOO
? ? XAAO
不是(不存在中心點)。
輸入描述:
第一行兩個整數n, m表示矩陣的大小 (1 <= n, m <= 500);接下來 n 行,每行一個長度為 m 的字符串表示矩陣,矩陣元素保證由X和O構成。
輸出描述:
一行一個整數表示最大的蝴蝶形狀的對角線的長度。 示例1輸入
5 5 XOOOO XXOOO XOXOO XXOOO XOOOO輸出
5#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char mp[508][508]; int n,m; bool Ju(int x,int y,int k,int size){if(mp[x+k][y+k]=='O'||mp[x+k][y+size-1-k]=='X') return true;if(mp[x+size-1-k][y+k]=='O'||mp[x+size-1-k][y+size-1-k]=='X') return true;return false; } int main(){scanf("%d%d",&n,&m);for(int i=0;i<n;++i) scanf("%s",mp[i]);int maxx=min(n,m);if((maxx&1)^1) --maxx;bool ok=0;for(int size=maxx;~size;size-=2) if(ok) break; else for(int i=0;i<=n-size;++i){int sj=(size+1)/2;for(int j=0;j<=m-size;++j) {if(mp[i+sj-1][j+sj-1]!='X') continue;bool fl=1;for(int k=0;k<sj-1;++k) if(Ju(i,j,k,size)) {fl=0;break;}if(!fl) continue;for(int k=0;k<size;++k) if(mp[i+k][j]!='X') {fl=0;break; }if(!fl) continue;for(int k=0;k<size;++k) if(mp[i+k][j+size-1]!='O'&&size!=1) {fl=0;break;}if(fl) {ok=1;break;}}if(ok) {printf("%d\n",size);break;}}if(!ok) puts("0"); }
?
轉載于:https://www.cnblogs.com/mfys/p/7818846.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Wannafly挑战赛3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 循环和判断
- 下一篇: 2017 ACM/ICPC(西安)赛后总