A了9題ios
不太行c++
雖然前期速度還行,因爲有道poj原題寫過直接粘了,但中期因爲被B卡了,心態有點炸。後面也作不太動。算法
來補兩道題。ide
B題:spa
題意:求最短的讓全部字符都至少出現一次的字符串的長度debug
https://ac.nowcoder.com/acm/contest/3570/B指針
比賽裏一直想的假算法,什麼維護每一個字符第一次出現,最後一次出現的位置,那答案在中間呢? 枚舉長度,端點,check,TLE,真敢寫。真的sb,太假了。code
而後這題賽後看了別人代碼,發現相似個滑動窗口,動態的去維護呀,雖然我中間也有想到雙指針動態,但我他喵的,兩個指針一直在一塊兒動,毫無條理。blog
而後作法就是設置一個指針下標l,讓另外一個指針下標i不斷右移同時維護有不一樣字符出現的次數,而對於左指針l,只要他所在位置字符出現次數大於1,他在的地方就是能夠移動的,顯然答案更優。ci
而後只要你統計的區間不一樣字符數達到要求了,便可加入答案取min。
我都寫題解了
下 次 一 定 要 會 作!
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #ifndef ONLINE_JUDGE 5 #define debug(x) cout << #x << ": " << x << endl 6 #else 7 #define debug(x) 8 #endif 9 10 const int MAXN=2e5+7; 11 const int INF=0x3f3f3f3f; 12 const int MOD=1e9+7; 13 14 int main() 15 { 16 ios::sync_with_stdio(false); 17 cin.tie(0); 18 int n; 19 string s; 20 cin>>n>>s; 21 set<char>st; 22 for(int i=0;i<s.size();++i) 23 st.insert(s[i]); 24 debug(st.size()); 25 int l=0; 26 int ans=INF; 27 map<char,int>vis; 28 for(int i=0;i<s.size();++i) 29 { 30 vis[s[i]]++; 31 while(vis[s[l]]>1) {vis[s[l]]--;l++;} 32 if(vis.size()==st.size()) ans=min(ans,i-l+1); 33 } 34 cout<<ans<<endl; 35 return 0; 36 }
再來個L題
L題:
題意:求最小的m階矩陣,m階矩陣是n階矩陣的一部分,使得m階矩陣內的元素和很多於k
又是一道一看別人代碼就明白了的題
其實就是關於求任意一個矩陣內元素和的簡單容斥
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
處理出這個,check的時候根據mid也相似容斥找有沒有符合的。
答案顯然單調能夠二分
而後我本身不知道想什麼騷方法處理出任意m階矩陣....反正就是沒搞出來。。。。
容斥啊!
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #ifndef ONLINE_JUDGE 5 #define debug(x) cout << #x << ": " << x << endl 6 #else 7 #define debug(x) 8 #endif 9 10 const int MAXN=2e3+7; 11 const int INF=0x3f3f3f3f; 12 const int MOD=1e9+7; 13 14 ll a[MAXN][MAXN]; 15 ll sum[MAXN][MAXN]; 16 ll n,k; 17 18 bool check(int mid) 19 { 20 for(int i=1;i+mid-1<=n;++i) 21 { 22 for(int j=1;j+mid-1<=n;++j) 23 { 24 if((sum[i+mid-1][j+mid-1]-sum[i-1][j+mid-1]-sum[i+mid-1][j-1]+sum[i-1][j-1]) >= k) 25 return true; 26 } 27 } 28 return false; 29 } 30 int main() 31 { 32 ios::sync_with_stdio(false); 33 cin.tie(0); 34 cin>>n>>k; 35 for(int i=1;i<=n;++i) 36 { 37 for(int j=1;j<=n;++j) 38 { 39 cin>>a[i][j]; 40 sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j]; 41 } 42 } 43 if(sum[n][n]<k) 44 cout<<"I'm a Gold Chef!"<<endl; 45 else 46 { 47 int ans=0; 48 int l=1,r=n; 49 while(l<=r) 50 { 51 int mid=l+r>>1; 52 if(check(mid)) 53 { 54 ans=mid; 55 r=mid-1; 56 } 57 else 58 l=mid+1; 59 } 60 cout<<ans<<endl; 61 } 62 63 return 0; 64 }