A了9题
不太行
虽然前期速度还行,由于有道poj原题写过直接粘了,但中期由于被B卡了,心态有点炸。后面也做不太动。
来补两道题。
B题:
题意:求最短的让所有字符都至少出现一次的字符串的长度
https://ac.nowcoder.com/acm/contest/3570/B
比赛里一直想的假算法,什么维护每个字符第一次出现,最后一次出现的位置,那答案在中间呢? 枚举长度,端点,check,TLE,真敢写。真的sb,太假了。
然后这题赛后看了别人代码,发现类似个滑动窗口,动态的去维护呀,虽然我中间也有想到双指针动态,但我他喵的,两个指针一直在一起动,毫无条理。
然后做法就是设置一个指针下标l,让另一个指针下标i不断右移同时维护有不同字符出现的次数,而对于左指针l,只要他所在位置字符出现次数大于1,他在的地方就是可以移动的,显然答案更优。
然后只要你统计的区间不同字符数达到要求了,即可加入答案取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 }