日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

校内集训(20170903)

發布時間:2024/4/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 校内集训(20170903) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

T1:卡片(card)

【題目描述】

lrb喜歡玩卡牌。他手上現在有張牌,每張牌的顏色為紅綠藍中的一種。現在他有兩種操作。一是可以將兩張任意位置的不同色的牌換成一張第三種顏色的牌;二是可以將任意位置的兩張相同顏色的牌換成一張該顏色的牌。兩個操作后都可以將生成的牌放到任意位置。現在他想知道,最后一張牌可能是什么顏色的。

【輸入描述】

第一行輸入一個,表示卡牌數量。

第二行輸入一個由’B’,’G’,’R’組成的長度為的字符串,分別表示卡牌的顏色為藍色、綠色、紅色中的一種。

【輸出描述】

輸出’B’,’G’,’R’中的若干個字母,按字典序輸出。代表可能的最后一張牌的顏色。

【樣例】

輸入1

輸出1

2

RB

G

輸入2

輸出2

3

GRG

BR

輸入3

輸出3

4

BBBB

B

【數據范圍】

對于100%的數據,n<=200

——————————————————我是分割線————————————————————

這是一道簡單分析題。(入門難度。。不要吐槽)

很顯然我們發現如果3張牌都超過一張,三種情況都會出現(BGR)

那么如果有2張牌都超過2張,同上

剩下3種情況:

1,1,0(數字表示牌的數量)那么答案就是牌數是0的那張

2,1,0(2表示2張以上)那么答案就是牌數為1和0的兩張

1,0,0(1表示一張以上)那么答案就是牌數為1的那一張

然后。。。做完了

下面貼上代碼

#include<cstdio> using namespace std; int a[4],n; int er,yi,sa; char ch; char ans[3]={'B','G','R'}; void swap(int &a,int &b){a^=b;b^=a;a^=b;} int main(){freopen("card.in","r",stdin);freopen("card.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++){ch=getchar();while(ch<'A'||ch>'Z')ch=getchar();if(ch=='B')a[1]++;else if(ch=='G')a[2]++;else if(ch=='R')a[3]++;}for(int i=1;i<=3;i++)if(a[i]>=2)er++;for(int i=1;i<=3;i++)if(a[i]>=1)yi++; if(er>=2||yi==3)puts("BGR");else if(er==1&&yi==2){int x,y;for(int i=1;i<=3;i++)if(a[i]==0)x=i;else if(a[i]==1)y=i;if(x>y)swap(x,y);printf("%c%c\n",ans[x-1],ans[y-1]);}else if(yi==2){int x;for(int i=1;i<=3;i++)if(!a[i])x=i;printf("%c\n",ans[x-1]);}else if(yi==1){int x;for(int i=1;i<=3;i++)if(a[i])x=i;printf("%c\n",ans[x-1]);}fclose(stdin);fclose(stdout); }

————————————————我是分割線——————————————————

T2:取數(win)

【題目描述】

lrb目前有個數字,他想知道這個數中選出若干個數,平均數減中位數的最大值是多少。可以證明,對于一個遞增數列,如果是平均數減中位數最大時的中位數,表示在兩邊分別取相鄰數字的數量,表示以為中位數,在兩側各取相鄰個數時平均數減中位數的值,那么為關于的單峰函數。

【輸入描述】

第一行為,為數字個數。

第二行有個數,分別代表個數字。

【輸出描述】

輸出一個數,為平均數減中位數的最大值,保留兩位小數。

【樣例】

輸入

輸出

4

1 2 3 4

0.33

【數據范圍】

對于60%的數據,n<=21

對于75%的數據,n<=1000

對于100%的數據,n<=10^5,0<=ai<=10^6

——————————————————我是分割線————————————————————

這題首先我們要想到的就是枚舉中位數。

那么假設我們已知某一個數是中位數,那么我們怎么求最優的答案呢?

對于一個已經排序過的數列,

顯然我們要在這個中位數的左邊和右邊同時取相同數量的數。

對于中位數的左邊,顯然越靠近中位數的數越優,

對于中位數的右邊,越遠離中位數的數越優。

所以對于第i個數作為中位數的情況,我們左邊從第i-1位開始向左取數,右邊從第n位開始向左取數。而取數的個數自然就是三分啦!(三分的過程用前綴和O(1)求平均數)

至于為什么偶數個數的數列不是最優解,這個我留個坑以后來填。

下面貼代碼(當然我寫了偶數版本)

#include<cstdio> #include<algorithm> #define MN 100005 using namespace std; int a[MN],n; long long sum[MN]; double ans=-100000000; int main(){freopen("win.in","r",stdin);freopen("win.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);sort(a+1,a+n+1);int l=0,r=0,lm=0,rm=0,le=0;double la=a[1],ra=a[1];for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];for(int i=1;i<=n;i++){le=min(i-1,n-i);le=max(le,0);l=0,r=le;while(l<r-1){lm=l+(r-l)/3,rm=r-(r-l)/3;la=(double)(sum[i-1]-sum[i-1-lm]+sum[n]-sum[n-lm]+a[i])/(double)(2*lm+1);ra=(double)(sum[i-1]-sum[i-1-rm]+sum[n]-sum[n-rm]+a[i])/(double)(2*rm+1);if(la<ra)l=lm+1;else r=rm-1;}la=(double)(sum[i-1]-sum[i-1-l]+sum[n]-sum[n-l]+a[i])/(double)(2*l+1);ra=(double)(sum[i-1]-sum[i-1-r]+sum[n]-sum[n-r]+a[i])/(double)(2*r+1);if(la<ra)ans=max(ans,ra-(double)a[i]);else ans=max(ans,la-(double)a[i]);}la=ra=(double)(a[1]+a[2])/2.0;for(int i=1;i<n;i++){le=min(i-1,n-i-1);le=max(le,0);l=0,r=le;while(l<r-1){lm=l+(r-l)/3,rm=r-(r-l)/3;la=(double)(sum[i-1]-sum[i-1-lm]+sum[n]-sum[n-lm]+a[i]+a[i+1])/(double)(2*lm+2);ra=(double)(sum[i-1]-sum[i-1-rm]+sum[n]-sum[n-rm]+a[i]+a[i+1])/(double)(2*rm+2);if(la<ra)l=lm+1;else r=rm-1;}la=(double)(sum[i-1]-sum[i-1-l]+sum[n]-sum[n-l]+a[i]+a[i+1])/(double)(2*l+2);ra=(double)(sum[i-1]-sum[i-1-r]+sum[n]-sum[n-r]+a[i]+a[i+1])/(double)(2*r+2);if(la<ra)ans=max(ans,ra-(double)((double)(a[i]+a[i+1])/(double)2));else ans=max(ans,la-(double)((double)(a[i]+a[i+1])/(double)2));}printf("%.2lf\n",ans);fclose(stdin);fclose(stdout); }

?————————————————我是分割線————————————————

T3:密碼(key)

【題目描述】

lrb去柜員機取錢,并輸入了他的四位密碼。但是這一切都被一個黑幫拍攝了下來。幸好,這一次他的銀行卡里并沒有剩余任何錢。lrb知道了他的賬戶被異常登錄后十分害怕,然后修改了他的密碼。從此以后他為了不被看出密碼,他開始“徐晃”。但這一切還是被拍攝了下來,拍攝多次以后,這個黑幫找到了你,希望你在一秒內幫他算出lrb的可能使用的密碼數量。

【輸入描述】

第一行輸入一個,為lrb被拍攝的動作次數。

接下來行,每行第一個數為,表示lrb接下來的手指移動次數,接下來為一個長度為的數字串,表示lrb手指經過的軌跡。lrb手指經過的位置,可能沒有按,也有可能按了多次。

【輸出描述】

輸出一行,為可能的密碼數量。

【樣例】

輸入

輸出

2

3 123

3 234

5

解釋

lrb可能用的是2222,2223,2233,2333,3333五種密碼

【數據范圍】

設所有軌跡串的總長度為。

對于35%的數據,L<5000

對于100%的數據,1<=n<=1000,1<=t<=10^4,L<=10^6

——————————————————我是分割線——————————————————

這道題有一個簡單思路(想不到的都是腦子抽了,比如我)

我們只要枚舉所有的密碼就好了

然后就是如何在O(n)時間內check一個密碼

我們只要開一個數組記錄從每一位開始,后面的第一個0-9分別在第幾位,如果都能夠找到,那么密碼合法。

下面貼代碼

#include<cstdio> #define MN 1005 #define M 1000005 #define F(x,l,r) for(int x=l;x<=r;x++) using namespace std; char e[M];int f[M][10],ans,n,t[MN]; int main(){freopen("key.in","r",stdin);freopen("key.out","w",stdout);scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%s",&t[i],e+t[i-1]),t[i]+=t[i-1];for(int i=0;i<=9;i++)f[t[n]][i]=t[n];for(int i=t[n]-1;i>=0;i--){for(int j=0;j<=9;j++)f[i][j]=f[i+1][j];f[i][e[i]-'0']=i;}F(a,0,9)F(b,0,9)F(c,0,9)F(d,0,9){int tot=0;F(i,0,n-1)if(f[f[f[f[t[i]][a]][b]][c]][d]<t[i+1])tot++;ans+=tot==n;}printf("%d\n",ans); }

?

轉載于:https://www.cnblogs.com/ghostfly233/p/7473367.html

總結

以上是生活随笔為你收集整理的校内集训(20170903)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。