找矩陣

D06發表於2024-08-21
  • 透過矩陣轉置,歸併行、列兩種情況
  • 先行後列表示座標
點選檢視程式碼
#include <bits/stdc++.h> 
using namespace std;
char c[3005][3005];
int s[3005][3005],u,v,n,m,l[3005],r[3005];
bool f;
int calc(int x1,int y1,int x2,int y2)
{
    return s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
}
void solve1()
{
    for(int i=1;i<=n;i++)
    {
        if(c[i][v]=='.'||c[i][v]=='S')
        {
            l[i]=r[i]=v;
            while(c[i][l[i]-1]=='.'||c[i][l[i]-1]=='S')
            {
                l[i]--;
            }
            while(c[i][r[i]+1]=='.'||c[i][r[i]+1]=='S')
            {
                r[i]++;
            }
        }
    }
    int x1=u;
    for(int x2=1;x2<x1;x2++)
    {
        if(c[x2][v]!='#')
        {
            bool f1=false,f2=false;
            int cnt=0;
            for(int y=max(l[x1],l[x2]);y<=min(r[x1],r[x2]);y++)
            {
                if(calc(x2,y,x1,y)==x1-x2+1)
                {
                    f1|=(y<=v);
                    f2|=(y>=v);
                    cnt++;
                    if(f1&&f2&&cnt>=2)
                    {
                    	f=true;
                    	break;
                    }
                }
            }
        }
    }
    for(int x2=x1+1;x2<=n;x2++)
    {
        if(c[x2][v]!='#')
        {
            bool f1=false,f2=false;
            int cnt=0;
            for(int y=max(l[x1],l[x2]);y<=min(r[x1],r[x2]);y++)
            {
                if(calc(x1,y,x2,y)==x2-x1+1)
                {
                    f1|=(y<=v);
                    f2|=(y>=v);
                    cnt++;
                    if(f1&&f2&&cnt>=2)
                    {
                    	f=true;
                    	break;
                    }
                }
            }
        }
    }
}
void solve2()
{
    for(int i=1;i<=m;i++)
    {
        if(c[u][i]=='.'||c[u][i]=='S')
        {
            l[i]=r[i]=u;
            while(c[l[i]-1][i]=='.'||c[l[i]-1][i]=='S')
            {
                l[i]--;
            }
            while(c[r[i]+1][i]=='.'||c[r[i]+1][i]=='S')
            {
                r[i]++;
            }
        }
    }
    int y1=v;
    for(int y2=1;y2<y1;y2++)
    {
        if(c[u][y2]!='#')
        {
            bool f1=false,f2=false;
            int cnt=0;
            for(int x=max(l[y1],l[y2]);x<=min(r[y1],r[y2]);x++)
            {
                if(calc(x,y2,x,y1)==y1-y2+1)
                {
                    f1|=(x<=u);
                    f2|=(x>=u);
                    cnt++;
                    if(f1&&f2&&cnt>=2)
                    {
                    	f=true;
                    	break;
                    }
                }
            }
        }
    }
    for(int y2=y1+1;y2<=m;y2++)
    {
        if(c[u][y2]!='#')
        {
            bool f1=false,f2=false;
            int cnt=0;
            for(int x=max(l[y1],l[y2]);x<=min(r[y1],r[y2]);x++)
            {
                if(calc(x,y1,x,y2)==y2-y1+1)
                {
                    f1|=(x<=u);
                    f2|=(x>=u);
                    cnt++;
                    if(f1&&f2&&cnt>=2)
                    {
                    	f=true;
                    	break;
                    }
                }
            }
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>c[i][j];
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+(c[i][j]!='#');
            if(c[i][j]=='S')
            {
                u=i;
                v=j;
            }
        }
    }
    solve1();
    solve2();
    if(f==true)
    {
        cout<<"Yes"<<endl;
    }
    else
    {
        cout<<"No"<<endl;
    }
    return 0;
}
/*
(x1,y1) (x1,y2)
(x2,y1) (x2,y2)
*/

相關文章