2019暑期牛客多校第三场

B题:Crazy Binary String

这个B题最长01子序列这个就很明显了

我们取0,1中最少的那个数的2倍,这样的话,显然是最优的   这个还是很好做的

但是我们对这个01均衡的串的话我们该怎么操作呢?

一个很naive的想法是这个串有什么性质呢:  0  1 的数量相同  ,那么  0 1就可以相互抵消  ,只要两个对于对应的奇数位和两个对应的偶数位中间的01能互相消掉的话

那么我们可以就可以算贡献,这个的话就随便搞搞就ok了

还有一钟想法是二分长度,然后check,这个是有问题的  比如说  11000011   这个的话8是可以,4是不行的   

关于这个杨例怎么造呢,我也不知道啊????????????????????????????????

这个也没啥办法,只能靠自己领会了   

下面是代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <bitset>
 7 typedef long long ll;
 8 using namespace std;
 9 const int maxn=(int)(1e5+2000);
10 int n;
11 char s[maxn];
12 int qilen[maxn*2],oulen[maxn*2];
13 int main(){
14     scanf("%d",&n);
15     scanf("%s",s+1);
16     memset(qilen,-1,sizeof(qilen));
17     memset(oulen,-1,sizeof(oulen));
18     int cnt0=0,cnt1=0;
19     int ans=0;
20     oulen[maxn]=0;
21     int q=maxn;
22     //cout<<q<<endl;
23     for(int i=1;i<=n;i++){
24         if(s[i]=='0') cnt0++;
25         else cnt1++;
26         if(s[i]=='0') q--;
27         else q++;
28        // cout<<q<<endl;
29         if(i%2==1){
30             if(qilen[q]==-1) qilen[q]=i;
31             else{
32                 ans=max(ans,(i-qilen[q]));
33             }
34         }else{
35             if(oulen[q]==-1) oulen[q]=i;
36             else ans=max(ans,i-oulen[q]);
37         }
38     }
39     printf("%d %d\n",ans,2*min(cnt0,cnt1));
40     return 0;
41 }
View Code

H题:Magic Line

这个题的话我们首先想一下怎么分成两半,一个最简单的想法是排序,排完序之后   

因为是偶数个吗,中点自然就出现了

然后在中间的点把他们分开,具体用一个两个1e9,-1e9的点来分开就ok,这样还是挺好操作的。大概一下子就能搞掉

下面是代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <bitset>
 7 typedef long long ll;
 8 using namespace std;
 9 const int maxn=1100;
10 const ll Max=(ll)(1e9);
11 int t,n;
12 struct point{
13     ll xi,yi;
14 };
15 point sum[maxn];
16 
17 bool cmp(point p1,point p2){
18     if(p1.xi==p2.xi) return p1.yi<p2.yi;
19     else return p1.xi<p2.xi;
20 }
21 
22 int main(){
23     scanf("%d",&t);
24     while(t--){
25         scanf("%d",&n);
26         for(int i=1;i<=n;i++) scanf("%lld%lld",&sum[i].xi,&sum[i].yi);
27         sort(sum+1,sum+n+1,cmp);
28         int m=n/2;
29         if(sum[m].xi==sum[m+1].xi){
30             if((sum[m+1].yi-sum[m].yi)%2==1){
31                 printf("%lld %lld %lld %lld\n",sum[m].xi-1,(ll)(3e8)+sum[m+1].yi,sum[m].xi+1,sum[m].yi-(ll)(3e8));
32             }else{
33                 ll y=(sum[m+1].yi+sum[m].yi)/2;
34                 printf("%lld %lld %lld %lld\n",sum[m].xi-1,(ll)(3e8)+y,sum[m].xi+1,y-(ll)(3e8));
35             }
36         }else{
37             ll y=(sum[m].yi+sum[m+1].yi)/2;
38             printf("%lld %lld %lld %lld\n",sum[m].xi,y+(ll)(3e8),sum[m+1].xi,y-(ll)(3e8));
39         }
40     }
41     return 0;
42 }
View Code

F题:Planting Trees

这个的话我们怎么搞呢?????

首先我们知道如果我们要得到最大的区间,在根据他给的数据,知道这个东西某种情况下是需要穷举的,这个的话是要靠我们来努力发现的。

我觉得每道acm题目都是一道道模拟题,   他会给你一个条件,然后我们根据这些条件,应用上来,用这些应用上来的东西发现一个一个的性质,最后

根据性质我们得出这个题目的做法,这个是一般的Acm题的做法

    

猜你喜欢

转载自www.cnblogs.com/pandaking/p/12112464.html