• 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
    ",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
    ",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
    ",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
    ",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题的做法

    首先我们想看一个矩形怎么合格呢,就是这个矩形的最大值-最小值>m

    按照一般的想法我们得枚举出矩形的上边界,下边界,左边界,右边界。然后根据这几个边界中的最大值-最小值>m来做这道题,但是这样就会出现一个问题。

    我们这样搞虽然可以通过缓存  然后把题目的复杂度变成n^4来做,但是这个n^4的话显然是会超时的,所以面对这样的情况,我们需要更改一下子,我们枚举上下边界后

    肯定可以知道每一列中那个对应的每一列的最大值和最小值,然后我们根据这个最大值,最小值来慢慢操作。

    一个显然可以确定的一点是我们可以枚举右边界,然后左边届其实会随着右边界慢慢缩小的,其实这样的话我们只需要维护左边届,缩小的那个条件,我们就可以o(n)完成某个上边界和下边界的操作

    没错,就是这样子弄的,我们于是可以枚举右边界,右边界不断向右移动,然后维护一个左边的指针,他一共移动n次。然后我们维护一个最大值单调递减的队列,最小值单调递增的队列。每次把当前边界入队

    然后我们看一下最大值-最小值能不能满足条件,不能,l++,把不满足条件的出队即可。

    注意一点,这道题常数很大,我们不能通过deque来做,否则会t,我们只能用手写的双端队列,并且当我们在做这道题的时候,还得注意一下

    我一开始加了个不必要的特判,然后一直死t,最后删掉了特判,一下子就过了。

    下面是代码:

     1 #include <cstring>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cmath>
     5 #include <bitset>
     6 #include <cstdio>
     7 #include <queue>
     8 typedef long long ll;
     9 using namespace std;
    10 const int maxn=550;
    11 int t,n,m,ans=0;
    12 int num[maxn][maxn];
    13 int mx[maxn],mn[maxn];
    14 int que1[maxn*2],que2[maxn*2];
    15 
    16 void solve(){
    17     for(int i=1;i<=n;i++){
    18         for(int j=1;j<=n;j++){ mx[j]=0;mn[j]=(int)(1e9+7);}
    19         for(int j=i;j<=n;j++){
    20             //  确定 起点,确定终点
    21             for(int k=1;k<=n;k++){
    22                 mx[k]=max(mx[k],num[j][k]);
    23                 mn[k]=min(mn[k],num[j][k]);
    24             }
    25             int l=1;//做边界
    26             int head1,tail1,head2,tail2; head1=tail1=head2=tail2=1;
    27             //维护一个最大值的双端队列  维护一个最小值的双端队列
    28             for(int k=1;k<=n;k++){
    29                 while(head1<tail1&&mx[que1[tail1]]<mx[k]){
    30                     tail1--;
    31                 }que1[++tail1]=k;
    32                 while(head2<tail2&&mn[que2[tail2]]>mn[k]){
    33                     //if(i==1&&j==1) cout<<"aakkkkk"<<endl;
    34                     tail2--;
    35                 } que2[++tail2]=k;
    36 
    37                 while(head1<tail1&&head2<tail2&&mx[que1[head1+1]]-mn[que2[head2+1]]>m){
    38                     l++;
    39                     while(head1<tail1&&que1[head1+1]<l) head1++;
    40                     while(head2<tail2&&que2[head2+1]<l) head2++;
    41                 }
    42                 ans=max(ans,(k-l+1)*(j-i+1));
    43             }
    44             // cout<<i<<"   "<<j<<"   "<<ans<<endl;
    45         }
    46     }
    47 }
    48 
    49 int main(){
    50     scanf("%d",&t);
    51     while(t--){
    52         scanf("%d%d",&n,&m);
    53         ans=0;
    54         for(int i=1;i<=n;i++)
    55             for(int j=1;j<=n;j++)
    56                 scanf("%d",&num[i][j]);
    57         solve();
    58         printf("%d
    ",ans);
    59     }
    60     return 0;
    61 }
    View Code

        

  • 相关阅读:
    composer的使用
    tp5短信接口的使用
    PHP序列化与反序列化
    PHP 的oop思想
    php单例模式
    统计图的使用(chart)
    jq的时间插件
    php中Excel操作
    Linux 常用命令
    think cmfx目录结构
  • 原文地址:https://www.cnblogs.com/pandaking/p/12112464.html
Copyright © 2020-2023  润新知