51nod1562-模拟&好题&链表|线段树-玻璃切割

来源:互联网 发布:mac上看美剧的软件 编辑:程序博客网 时间:2024/05/01 14:58

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1562
给定一个玻璃,m*n大小,可以横向切割或者纵向切割。
问你每次切割,他的最大的一块有多大
没想到这个方法。虽然很容易想到。
模拟链表,再每个节点中 算出他和左边节点的距离 ,同时更新他的左边节点和 他左边节点的右边节点。
最后再临界处搞一下右节点。,就可以把所有节点的左右都搞定
注意反着来。先删除第一个,就是倒数第二种情况,所以我用的stack
网上有一个 set的写法 据说超时 ,
好像还有线段树,但是不会写qwq

#include <bits/stdc++.h>using namespace std;/* 模拟,没有想到这样写。*/typedef long long ll;const int maxn=2e5+1000;bool x[maxn];bool y[maxn];stack<ll>v;struct ED{   char a;int b;}ed[maxn];struct Node{   int l,r,val;}fx[maxn],fy[maxn];int bigx,bigy;int m,n;int num;int main(){   //freopen("E://solve/tex1.txt","r",stdin);    //freopen("E://solve/tex2.txt","w",stdout);    while(~scanf("%d%d%d",&m,&n,&num)){          bigx=0;          bigy=0;          memset(x,0,sizeof(x));          memset(y,0,sizeof(y));          for(int i=1;i<=num;i++){              scanf(" %c%d",&ed[i].a,&ed[i].b);              if(ed[i].a=='H'){                 x[ed[i].b]=true;                 //cout<<ed[i].b<<endl;              }              else                y[ed[i].b]=true;          }          int loc=0;          int i;          x[n]=1;y[m]=1;          for( i=0;i<=n;i++){             if(x[i]){               fx[i].l=loc;                fx[loc].r=i;                fx[i].val=i-loc;                loc=i;                bigx=max(bigx,fx[loc].val);             }          }          fx[loc].r=n;          loc=0;          for(i=0;i<=m;i++){             if(y[i]){               //cout<<i<<endl;               fy[i].l=loc;                fy[loc].r=i;                fy[i].val=i-loc;                loc=i;                bigy=max(bigy,fy[loc].val);             }          }          fy[loc].r=m;          /*for(int i=1;i<=m;i++){             if(ed[i].a=='H')             printf("%d %d\n",fx[ed[i].b].l,fx[ed[i].b].r,fx[ed[i].b].val);             else               printf("%d %d\n",fy[ed[i].b].l,fy[ed[i].b].r,fy[ed[i].b].val);          }          cout<<endl;*/         // cout<<bigx*bigy<<endl;         v.push(1ll*bigx*bigy);         for(int i=num;i>1;i--){             if(ed[i].a=='H'){                int ans;                ans=fx[ed[i].b].val+fx[fx[ed[i].b].r].val;                fx[fx[ed[i].b].l].r=fx[ed[i].b].r;                fx[fx[ed[i].b].r].l=fx[ed[i].b].l;                //fx[ed[i].b].val=0;                fx[fx[ed[i].b].r].val=ans;                bigx=max(bigx,ans);             }             else{                    int ans;                //cout<<fy[ed[i].b].val<<"*****"<<endl;                ans=fy[ed[i].b].val+fy[fy[ed[i].b].r].val;                fy[fy[ed[i].b].l].r=fy[ed[i].b].r;                fy[fy[ed[i].b].r].l=fy[ed[i].b].l;                //fy[ed[i].b].val=0;                fy[fy[ed[i].b].r].val=ans;                bigy=max(bigy,ans);             }             v.push(1ll*bigx*bigy);         }         while(!v.empty()){             printf("%lld\n",v.top());             v.pop();         }    }    return 0;}
原创粉丝点击