12.28西南民族大学第十一届程序设计竞赛(同步赛)

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 }
View Code

再来个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 }
View Code

猜你喜欢

转载自www.cnblogs.com/Zzqf/p/12112916.html
今日推荐