原题解链接:https://ac.nowcoder.com/discuss/149990

东西:形状和排列顺序。先来看形状如何确定:题目里定义"连续的1序列”是不拐弯的,也就是说最优的答案一定会被两种摆放方式包含:

1:全横着放。

2:全竖着放。

我们先考虑全横着放的情况,竖着同理。对于全横着放的矩阵一共有44行, 由于序列不拐弯,所以分开考虑他们,最后取max即可。理(gan)性(xing)思(li)考(jie)一下一个作为答案的序列是什么样子的,显然它由三部分构成一个矩阵的后缀11数列(可以没有) , t(t>=0)t(t >= 0)个这行全为11的矩阵,一个矩阵的前缀11数列(可以没有) ,所以我们只要遍历一遍所有的矩阵,记录有几个矩阵这一行全为11, 并录最长的前后级,然后统计答案即可。

你还要考虑如果最长前缀和最长后缀出现在同一一个矩阵里的情况。

update:如果有人想深入探讨卡快读的方式,请联系qq: 2284953398。

update:赛后有位机智的同学告诉我还有一种诡异的情况,向他表示感谢,同时对造那么水的数据深表歉意。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

#define maxn 100001
#define int long long
using namespace std;

int n,ans;
int f[maxn][4][4];
int num[maxn][4][4];

int get_ans (int x){
	int res=0,hav=0;
	int q1=0,posq1=0;
	int q2=0,posq2=0;
	for(int i=1;i<=n;i++){
		int now=0;
		for(int j=1;j<=4;j++){
			if(num[i][x][j])	 now++;
			else 			 break;
		}
		if(now==4){
			hav++;
		}else if(now>q1){
			q2=q1,posq2=posq1;
			q1=now,posq1=i;
		}else if(now>q2){
			q2=now,posq2=i;
		}
	}
	int h1=0,posh1=0;
	int h2=0,posh2=0;
	for(int i=1;i<=n;i++){
		int now=0;
		for(int j=4;j;j--){
			if(num[i][x][j])	 now++;
			else				 break;
		}
		if(now==4){
			continue;
		}else if(now>h1){
			h2=h1,posh2=posh1;
			h1=now,posh1=i;
		}else if(now>h2){
			h2=now,posh2=i;
		}
	}
	if(posq1!=posh1){
		res=max(res,4*hav+q1+h1);
	}if(posq1!=posh2){
		res=max(res,4*hav+q1+h2);
	}if(posh1!=posq2){
		res=max(res,4*hav+q2+h1);
	}
	res=max(res,hav*4);
	return res;
}

int update (int x){
	int res=0;
	for(int i=1;i<=n;i++){
		int tmp=0;
		if(num[i][x][1]) continue;
		if(num[i][x][4]) continue;
		tmp=num[i][x][2]+num[i][x][3];
		res=max(res,tmp);
	}
	return res;
}

void rotate (int x){
	for(int i=1;i<=4;i++){
		for(int j=1;j<=4;j++){
			f[x][4-j+1][i]=num[x][i][j];
		}
	}
	for(int i=1;i<=4;i++){
		for(int j=1;j<=4;j++){
			num[x][i][j]=f[x][i][j];
		}
	}
}

void debug (int x){
	for(int i=1;i<=4;i++){
		for(int j=1;j<=4;j++)
			printf("%lld ",num[x][i][j]);
		printf("\n");
	}
	printf("\n");
}

signed main()
{
	scanf("%lld",&n);
	for(int t=1;t<=n;t++){
		for(int i=1;i<=4;i++){
			for(int j=1;j<=4;j++){
				scanf("%lld",&num[t][i][j]);
			}
		}
	}
	for(int i=1;i<=4;i++){
		ans=max(ans,get_ans(i));
		ans=max(ans,update(i));
	}
	for(int i=1;i<=n;i++){
		rotate(i);
	}
	for(int i=1;i<=4;i++){
		ans=max(ans,get_ans(i));
		ans=max(ans,update(i));
	}
	printf("%lld\n",ans);
	return 0;
}