牛客练习赛29 B 列队

【题解】

  把某一行或某一列有4个1的都统计出来,然后首尾接上尽量长的,注意首尾不能选上同一个矩阵,要维护前缀、后缀1最大值和次大值。

  还要注意维护矩阵内连续1的长度,因为可能有 0 0 0 0 这种情况。

                         0 1 1 0

                         0 1 1 0

                         0 0 0 0

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define LL long long
  5 #define rg register
  6 #define N 200010
  7 using namespace std;
  8 int n,m,b[4][4],ans[2][4],f[4],pos,pos2,Mx;
  9 bool v[2][4];
 10 struct rec{
 11     int l,r;
 12 }s[N][2][4];
 13 inline int read(){
 14     int k=0,f=1; char c=getchar();
 15     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
 16     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
 17     return k*f;
 18 }
 19 int main(){
 20     n=read();
 21     for(rg int i=1;i<=n;i++){
 22         memset(v,0,sizeof(v));
 23         for(rg int j=0;j<4;j++)
 24             for(rg int k=0;k<4;k++) b[j][k]=read();
 25         if(b[1][1]||b[1][2]){
 26             int tmp=1;
 27             if(b[1][1]&&b[1][2]) tmp++;
 28             Mx=max(Mx,tmp);
 29         }
 30         if(b[2][1]||b[2][2]){
 31             int tmp=1;
 32             if(b[2][1]&&b[2][2]) tmp++;
 33             Mx=max(Mx,tmp);
 34         }
 35         if(b[1][1]||b[2][1]){
 36             int tmp=1;
 37             if(b[1][1]&&b[2][1]) tmp++;
 38             Mx=max(Mx,tmp);
 39         }
 40         if(b[1][2]||b[2][2]){
 41             int tmp=1;
 42             if(b[1][2]&&b[2][2]) tmp++;
 43             Mx=max(Mx,tmp);
 44         }
 45         for(rg int j=0;j<4;j++){
 46             bool ok=1;
 47             for(rg int k=0;k<4;k++)if(!b[j][k]) ok=0;
 48             if(ok) ans[0][j]+=4,v[0][j]=1;
 49         }
 50         for(rg int j=0;j<4;j++){
 51             bool ok=1;
 52             for(rg int k=0;k<4;k++)if(!b[k][j]) ok=0;
 53             if(ok) ans[1][j]+=4,v[1][j]=1;
 54         }
 55         for(rg int j=0;j<4;j++){
 56             if(v[0][j]) continue;
 57             for(rg int k=0;k<4;k++)if(b[j][k]){
 58                 s[i][0][j].l++;
 59             }
 60             else break;
 61             for(rg int k=3;k>=0;k--)if(b[j][k]){
 62                 s[i][0][j].r++;
 63             }
 64             else break;
 65         }
 66         for(rg int j=0;j<4;j++){
 67             if(v[1][j]) continue;
 68             for(rg int k=0;k<4;k++)if(b[k][j]){
 69                 s[i][1][j].l++;
 70             }
 71             else break;
 72             for(rg int k=3;k>=0;k--)if(b[k][j]){
 73                 s[i][1][j].r++;
 74             }
 75             else break;
 76         }
 77 //        for(rg int j=0;j<4;j++) printf("-%d ",s[i][0][j].l); puts("l");
 78 //        for(rg int j=0;j<4;j++) printf("-%d ",s[i][0][j].r); puts("r");
 79 //        for(rg int j=0;j<4;j++) printf("+%d ",s[i][1][j].l); puts("l");
 80 //        for(rg int j=0;j<4;j++) printf("+%d ",s[i][1][j].r); puts("r");
 81     }
 82     for(rg int j=0;j<2;j++){
 83         for(rg int k=0;k<4;k++){
 84             int mx=0,mx2=0,pos=0,pos2=0,mx3=0,mx4=0;
 85             for(rg int i=1;i<=n;i++){
 86                 if(s[i][j][k].l>mx){
 87                     mx=s[i][j][k].l;
 88                     pos=i;
 89                 }
 90             }
 91             for(rg int i=1;i<=n;i++){
 92                 if(s[i][j][k].l>mx2&&i!=pos) mx2=s[i][j][k].l;
 93             }
 94             for(rg int i=1;i<=n;i++){
 95                 if(s[i][j][k].r>mx3){
 96                     mx3=s[i][j][k].r;
 97                     pos2=i;
 98                 }
 99             }
100             for(rg int i=1;i<=n;i++){
101                 if(s[i][j][k].r>mx4&&i!=pos2) mx4=s[i][j][k].r;
102             }
103             if(pos!=pos2) ans[j][k]+=mx+mx3;
104             else ans[j][k]+=max(mx+mx4,mx2+mx3);
105 //            printf("[%d %d %d %d]
",mx,mx2,mx3,mx4);
106         }
107     }
108     for(rg int i=0;i<2;i++)
109         for(rg int j=0;j<4;j++) Mx=max(Mx,ans[i][j]);
110     printf("%d
",Mx);
111     return 0;
112 }
原文地址:https://www.cnblogs.com/DriverLao/p/9820620.html