搜索优化

xiaoxiao2021-02-28  85

题意:同一行或者列的炮台会被射到,求一个位置设炮台使得其炸掉的炮台最多

ac代码:

#include <bits/stdc++.h> #include <stdio.h> #define ff(i,x,y)for(int i=x;i<y+1;i++) #define fs(i,x,y)for(int i=x;i>y-1;i--) #define all(x) x.begin(),x.end() #define Ins(x) inserter(x,x.begin()) using namespace std; int n,m,p[4010],viscol[2010],visrow[2010],mes[4010],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; char mp[2010][2010]; vector<int>col[2010],row[2010]; typedef pair<int,int> pii; bool ppan(int x,int y) {     if(x>=1&&x<=n&&y>=1&&y<=m)     return true;     return false; } void bfs(int x,int y) {     queue<pii>hu;     pii now(x,y);     hu.push(now);     int sum=(col[now.second].size()+row[now.first].size());     sum--;     while(!hu.empty())     {         now=hu.front();         hu.pop();         int ne;         ff(i,0,col[now.second].size()-1)         {             ne=col[now.second][i];             if(!visrow[ne])             {                 visrow[ne]=1;                 p[ne]=p[x];                 ff(j,0,row[ne].size()-1)                 if(!viscol[row[ne][j]])                 sum++;                 hu.push(pii(ne,now.second));             }         }         ff(i,0,row[now.first].size()-1)         {             ne=row[now.first][i];             if(!viscol[ne])             {                 viscol[ne]=1;                 p[ne+n]=p[x];                  ff(j,0,col[ne].size()-1)                 if(!visrow[col[ne][j]])                 sum++;                 hu.push(pii(now.first,ne));             }         }     }     mes[p[x]]=sum; } int main() {     scanf("%d%d",&n,&m);     ff(i,1,n)     {         p[i]=i;         scanf("%s",mp[i]+1);         ff(j,1,m)         {             p[j+n]=j+n;             if(mp[i][j]=='+')             {                 col[j].push_back(i);                 row[i].push_back(j);             }         }     }     int res=0,posx,posy,hupan=0;     ff(i,1,n)     {         ff(j,1,m)         {             if(!viscol[j]&&!visrow[i]&&mp[i][j]=='+')             {                 viscol[j]=1;                 visrow[i]=1;                 p[j+n]=p[i];                 bfs(i,j);             }         }     }     ff(i,1,n)     {         ff(j,1,m)         {             int nownum=0;             if(mp[i][j]=='.')             {                 if(p[i]==p[j+n])                 nownum=mes[p[i]];                 else                 nownum=mes[p[i]]+mes[p[j+n]];             }             if(nownum>res)             {                 hupan=1;                 res=nownum;                 posx=i;                 posy=j;             }         }     }     if(hupan)     printf("%d\n%d %d",res,posx,posy);     else     printf("0");     return 0; }

关键:visrow viscol 去标记行列,标记每一个点会超时

转载请注明原文地址: https://www.6miu.com/read-42422.html

最新回复(0)