date: 2019-07-28ios
給你兩個不一樣的整數A
和B
,要求你找到一個整數K
,同時知足|A-K|=|B-K|
。找不到時,輸出"IMPOSSIBLE"
c++
聰明的讀者讀到這裏確定已經發現了,這其實就是平均數,可是,要特判A
和B
的差是奇數的狀況:此時K
不是整數,因此輸出"IMPOSSIBLE"
。git
#include<bits/stdc++.h> using namespace std; int a,b; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>a>>b; if((a+b)%2){//K不是整數 cout<<"IMPOSSIBLE"<<endl; }else{ cout<<(a+b)/2<<endl; } return 0; }
有一個長度爲N
的序列,內部元素爲1~N
。容許最多交換一次任意一對元素的位置,把這個序列變爲升序(從小到大的)序列(能夠選擇不交換也就是交換零次,但最多一次),能夠就輸出"YES"
,不然輸出"NO"
。算法
暴力。因爲這道題的數據範圍很小,因此只要模擬交換元素就好。數組
咱們跑一個二重循環表明交換的元素對,再在裏面寫一個循環判斷是否有序便可。特殊地,咱們須要直接判斷這個序列是否有序,由於題目裏說能夠不交換。優化
#include<bits/stdc++.h> using namespace std; int n; int a[55]; bool chk(){//檢查序列是否有序 for(int i=1;i<=n;i++){ if(a[i]<=a[i-1]){//其實由於是1~n的序列,能夠直接寫a[i]!=i判斷 return false; } } return true; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<n;i++){ for(int j=i+1;j<=n;j++){ swap(a[i],a[j]);//模擬交換位置 if(chk()){//有序了就輸出 cout<<"YES"<<endl; return 0; } swap(a[i],a[j]);//check完記得換回來 } } if(chk()){//特殊地,判斷數組一開始就有序的狀況 cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } return 0; }
有N+1
座城市,而後其中的第i
個城市有A[i]
個怪獸在,有N
個英雄,第i
個英雄能夠戰勝在第i
和i+1
城市的怪獸,但第i
位英雄戰勝的怪獸不超過B[i]
個。spa
貪心。顯然地,因爲第i
位英雄只能影響第i
和i+1
城市,因此i
以前的城市這位英雄都不能影響,因此儘可能讓第i
位英雄戰勝第i
座城市裏的怪物,打不完B[i]
個在去下一座城市。code
若是第i
位英雄優先擊殺第i+1
位的怪物,那麼第1座城市可能會有結餘,然後面的英雄由於本身的城市的怪物已經被殺掉一部分了,因此可能不能殺滿B[i]
個,因此以前的作法應該是最優的。圖片
#include<bits/stdc++.h> using namespace std; int n; int a[100005]; int b[100005]; long long ans; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n+1;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ cin>>b[i]; } for(int i=1;i<=n;i++){//貪心的,讓英雄先殺本身城市的怪物,再殺下一個城市的 if(b[i]<=a[i]){ ans+=b[i]; }else{ b[i]-=a[i]; ans+=a[i]; ans+=min(a[i+1],b[i]); a[i+1]-=min(a[i+1],b[i]); } } cout<<ans<<endl; return 0; }
給你一個字符串S
,包含0~9
和?
。在?
中填入0~9
,使得獲得的數對13
取模餘5
。ci
能夠有前導零
DP。因爲數據範圍很大,有10^5
那麼大,可是13
這個數字很小,是一個突破口。因而:
咱們創建一個二維數組DP
,DP[i][j]
表示計算到第i
位(第i
位尚未填入,此時i
從0
開始計算)時有多少種
對13
取模餘j
的方法。正向思考,DP[i+1][(j*10+<填入的數字>)%13]+=DP[i][j]
,若是這一位是?
,那麼填入的數字從1
到9
都要計算一遍。
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; string s; int n; int dp[100005][15]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>s; int n=s.size(); dp[0][0]=1; for(int i=0;i<n;i++){ if(s[i]=='?'){ for(int j=0;j<13;j++){ for(int k=0;k<10;k++){//嘗試填入0~9 dp[i+1][(j*10+k)%13]+=dp[i][j]; if(dp[i+1][(j*10+k)%13]>=mod)dp[i+1][(j*10+k)%13]-=mod;//常數優化 } } }else{ for(int j=0;j<13;j++){ dp[i+1][(j*10+s[i]-'0')%13]+=dp[i][j]; if(dp[i+1][(j*10+s[i]-'0')%13]>=mod)dp[i+1][(j*10+s[i]-'0')%13]-=mod;//常數優化 } } } cout<<dp[n][5]<<endl; return 0; }
其實這個常數優化並無什麼用,由於計算下標時仍是須要取模。
我不會,因此就沒有辦法寫了。
放張官方題解:
給你兩個字符串s
和t
,問你是否有一個非負整數i
知足下列條件而且i
是有限的,若是是,那麼求出i
的最大值。
條件:有一個非負整數j
,i
個t
鏈接起來是j
個s
鏈接起來的字串。
說人話(其實也是我比較喜歡的方式)就是給你兩個串s
和t
,而後無限多個s
鏈接起來,是否能夠找到有限個t
鏈接起來是s
的子串。若是無限多個t
都是字串,那麼就輸出-1
。
想法來自個人同窗。首先,你把足夠多的s
鏈接起來,而後每個位置i
都查看s
從i
開始的後綴子串並記爲s2
,查看t
是不是s2
的前綴。新開一個數組suf
記錄是或否。而後,從後往前,作一個相似前綴和的操做,若是第i
位是1
,那麼就加上第i+|t|
位的值(|t|
指t
的長度),能夠在O(n)
時間內求出最長的連續的t
做爲連續的s
的子串時,這個t
的連續的個數。
這個匹配操做,咱們可使用Hash
來把複雜度控制在O(n)
裏(其實KMP
和Z算法
也能夠實現)。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1145411919; const int p=810; //這麼臭的哈希值應該沒人會卡吧 string s,t; int ans; ll pw[16000005]; ll h[16000005]; ll ht[16000005]; int suf[16000005]; inline ll gh(int x){//求s中第x位開始的長|t|字符串的哈希值 if(x+t.size()>s.size())return -1; return (h[x+t.size()-1]-h[x-1]*pw[t.size()]%mod+mod)%mod; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>s>>t; while(s.size()<t.size()*2)s=s+s; s=s+s; s=s+s; s=s+s;//構建出足夠長的s pw[0]=1; for(int i=1;i<=16000000;i++){ pw[i]=pw[i-1]*p%mod; }//預先求k的i次方,存入pw[i] h[0]=s[0]-'a'+1; for(int i=1;i<s.size();i++){ h[i]=(h[i-1]*p+s[i]-'a'+1)%mod; }//h[i]表明s到i的hash值 ht[0]=t[0]-'a'+1; for(int i=1;i<t.size();i++){ ht[i]=(ht[i-1]*p+t[i]-'a'+1)%mod; }//ht[i]表明t到i的hash值 for(int i=0;i<s.size();i++){ suf[i]=ht[t.size()-1]==gh(i); }//suf功用同上 for(int i=s.size()-t.size();i>=0;i--){ if(suf[i])suf[i]+=suf[i+t.size()]; ans=max(ans,suf[i]); }//和作法中解釋的同樣 if(ans+1>=s.size()/t.size()){ cout<<-1<<endl; return 0; }//判斷t的鏈接是否過多,近似無限 cout<<ans<<endl; return 0; }
感謝你看完,若是你想支持我,你能夠登陸帳號,把對個人建議和意見寫在下面,幫助我取得進步。