12.28西南民族大學第十一屆程序設計競賽(同步賽)

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 }
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
相關文章
相關標籤/搜索