原题解链接:https://ac.nowcoder.com/discuss/149990
东西:形状和排列顺序。先来看形状如何确定:题目里定义"连续的1序列”是不拐弯的,也就是说最优的答案一定会被两种摆放方式包含:
1:全横着放。
2:全竖着放。
我们先考虑全横着放的情况,竖着同理。对于全横着放的矩阵一共有行, 由于序列不拐弯,所以分开考虑他们,最后取max即可。理(gan)性(xing)思(li)考(jie)一下一个作为答案的序列是什么样子的,显然它由三部分构成一个矩阵的后缀数列(可以没有) , 个这行全为的矩阵,一个矩阵的前缀数列(可以没有) ,所以我们只要遍历一遍所有的矩阵,记录有几个矩阵这一行全为, 并录最长的前后级,然后统计答案即可。
你还要考虑如果最长前缀和最长后缀出现在同一一个矩阵里的情况。
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;
}