本废物的第一篇博客,直接拿来了。(敌台题目)

传送门https://www.luogu.org/problemnew/show/P1141

裸上bfs会TLE,我们可以发现同一个连通图上的点的答案应该是一样的。所以选择用连通图来优化一下,速度超级加倍。

代码如下:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int map[1005][1005];
int flag[1005][1005],ans[1000005];//ans一定要开大一点 因为坐标可以有1e6种。
int toward[4][2]={0,1,0,-1,1,0,-1,0};
int n,m;
struct node{
    int x,y;
}p,head;
int bfs(int x,int y,int cnt){//我用了队列来写bfs,实际上数组也是ok的,有空更新数组写法,本质上是一样的。
    int ans=1;
    queue<node> q;
    p.x=x;
    p.y=y;
    q.push(p);
    while(!q.empty()){
        head=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            p.x=head.x+toward[i][0];
            p.y=head.y+toward[i][1];
            if(p.x<1||p.x>n||p.y<1||p.y>n||flag[p.x][p.y]!=0)
                continue;
            else{
                if(map[p.x][p.y]!=map[head.x][head.y]){
                    //book[p.x][p.y]=1;
                    q.push(p);
                    flag[p.x][p.y]=cnt;
                    ans++;
                }
            }
        }
    }
    return ans;
}
int main(){
    char t[1005];
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",t);
        for(int j=1;j<=n;j++){
            map[i][j]=t[j-1]-'0';//把坐标从字符串换成数字,不做这步也可以,下面的代码需要稍微改动。
        }
    }
    memset(flag,0,sizeof(flag));
    int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(flag[i][j]==0){
                flag[i][j]=++cnt;
                ans[cnt]=bfs(i,j,cnt);
            }
        }
    }
    int x,y;
    for(int i=0;i<m;i++){
        scanf("%d %d",&x,&y);
        printf("%d\n",ans[flag[x][y]]);
    }
    return 0;
}