本废物的第一篇博客,直接拿来了。(敌台题目)
传送门: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; }