哈爾濱理工大學第七屆程式設計競賽決賽(網路賽-高年級組)B題幸運大獎
阿新 • • 發佈:2019-01-31
幸運大獎
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld
題目描述
tabris實在是太窮了,為了發財,tabris去買了一張彩票,幸運地中了特別獎。
特別獎是這樣的,不會直接給你發錢.會給你一串二進位制數s,讓你在s中選擇一個不大於k的區間,這個區間表示的數就是獲獎者的獎金數目.
tabris中獎之後已經激動地蒙圈了,他不知道如何選擇能獲得最多的錢,你能幫幫他不?
輸入描述:
輸入一個整數T(T≤10),代表有T組資料.
每組資料佔兩行.
第一行有一個整數K(k≤60),代表tabris能選擇的數字區間的大小.
第二行有一個字串s(∣s∣≤106
保證 k≤∣s∣
輸出描述:
輸出一行"Case #x: y",x代表第x組資料,y代表tabris能得到的最多的錢。
示例1
輸入
3
1
10101
3
10101
5
10101
輸出
Case #1: 1
Case #2: 5
Case #3: 21
說明
對於第一個樣例,最大結果為1,選擇 [1]0101,10[1]01,1010[1] 。
對於第二個樣例,最大結果是5,選擇 [101]01,10[101]。
對於第三個樣例,最大結果為21,選擇 [10101]。
題目大意:
中文題目就不解釋,就是選取連續的K位數,使得結果最大
解題思路:
最先想到暴力,就按照題目的意思模擬,但是感覺會超時。想優化!
發現每次選定k個二進位制數以後往後移動的過程就是左移一位。需要判斷一下最前的一位和最後的一位,需要減去一些數。
最後發現,暴力可以過。按照題目意思做就能過。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<functional> #define ll long long using namespace std; char s[1000005]; int main() { int t; int i,j,k; int len; ll sum,ans,x; while(scanf("%d",&t)!=EOF) { for(i=1;i<=t;i++) { scanf("%d",&k); getchar(); scanf("%s",&s); len=strlen(s); sum=0; ans=0; x=1; for(j=k-1;j>=0;j--)//計算前K為二進位制數對應的十進位制數是多少 { sum+=(s[j]-'0')*x; x*=2; } ans=max(ans,sum); for(j=k;j<len;j++)//迴圈往後移動 { sum=sum<<1;//左移一位 if(s[j]=='1')//最後面一位是1 sum+=1;//需要加上1 if(s[j-k]=='1')//最前面一位是1 sum-=x;//需要減去2^k,不然這個數會一直留著,跟在後面移位 ans=max(ans,sum); } printf("Case #%d: %lld\n",i,ans); } } } /** 3 3 110110 5 101001111 */