【题解】CF1611G
CDFLS_mao_zx · · 题解
CF1611G
题意简述:
给定一张
赛场上的一些想法(错解):
1.考虑相邻两行,猜想其答案为每相邻两行答案的最大值,显然错误。
2.考虑转化成数字问题,发现
思路
赛场上问题的转化出现了一些问题,没有让问题变简单,所以考虑原问题。不妨先不考虑边界,如果走出了边界,直接对称回去。
我们通过观察发现不会从同一个点出发两次。考虑从左到右加入路径,如果一个点
然后是路径不会穿插,如果路径穿插了,那么找到第一个公共点,交换后面的部分,这样是等价的。
答案的上界是
有了这几条性质,就可以开始贪心了。我们从
然后是什么时候应该从
于是用一些 set 维护所有满足
代码(目前 CF 最短)
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int i,j,n,t,m,ans;
string str[N];
set<int> st[N];
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;ans=0;
for(i=1;i<=n;i++)
{
cin>>str[i];
for(j=1;j<=m;j++)
if(str[i][j-1]=='1')st[i+j].insert(i);
}
for(i=1;i<=n+m;i++)
{
if(st[i+1].size()==0)continue;
int pos=i;ans++;
for(j=1;j<=n;j++)
{
st[j+pos].erase(j);
if(st[j+pos].rbegin()!=st[j+pos].rend()&&*st[j+pos].rbegin()>j)pos--;
else pos++;
}
}
cout<<ans<<endl;
}
}