标签:情况 assert ons 题目 两种 扩展 字符 答案 定义
第一行两个整数n, m表示矩阵的大小(1 <= n, m <= 2000);
接下来n行,每行一个长度为m的字符串表示矩阵,矩阵元素保证由X和O构成。
一行一个整数表示最大的由X构成的蝴蝶形状的对角线的长度。
5 5 XOOOX XXOXX XOXOX XXOXX XOOOX
5
分析:蝴蝶形状可以分成两部分,|\和/|,预处理每个点这两种情况的最长长度;
最后枚举答案,bitset快速查询点对即可;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define inf 0x3f3f3f3f #define mod 998244353 #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls (rt<<1) #define rs (rt<<1|1) #define all(x) x.begin(),x.end() const int maxn=2e3+10; const int N=4e5+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;} int n,m,k,t; short ld[maxn][maxn],rd[maxn][maxn],dd[maxn][maxn]; vector<pair<short,short>>pl[maxn],pr[maxn]; bitset<maxn>bl[maxn],br[maxn]; char a[maxn][maxn]; int main(){ int i,j; scanf("%d%d",&n,&m); rep(i,1,n)scanf("%s",a[i]+1); for(i=n;i>=1;i--) { for(j=m;j>=1;j--) { if(a[i][j]==‘X‘) { ld[i][j]=ld[i+1][j-1]+1; dd[i][j]=dd[i+1][j]+1; rd[i][j]=rd[i+1][j+1]+1; } pl[min(dd[i][j],rd[i][j])].pb(mp(i,j)); pr[min(dd[i][j],ld[i][j])].pb(mp(i,j)); } } rep(i,1,m)rep(j,1,n)bl[i][j]=br[i][j]=1; int ret=0; for(i=1,j=0;i<=m;i+=2) { while(j<i) { for(auto &p:pl[j])bl[p.se][p.fi]=0; for(auto &p:pr[j])br[p.se][p.fi]=0; j++; } rep(k,1,m-i+1)if((bl[k]&br[k+i-1]).any()) { ret=i; break; } } printf("%d\n",ret); return 0; }
标签:情况 assert ons 题目 两种 扩展 字符 答案 定义
原文地址:http://www.cnblogs.com/dyzll/p/7758140.html