Ascnbeta @ 2024-07-07 15:25:52
基础的BFS,把STL的队列改成手写队列了,搜索结果也另外存储了,不知道还能怎么优化
#include <bits/stdc++.h>
using namespace std;
int n,m,ans;
int mp[1005][1005],a[1005][1005];
bool vis[1005][1005];
int l,r;
struct node {
int x,y;
}q[1000004];
int dx[5] = {0,1,-1,0,0},dy[5]= {0,0,0,-1,1};
inline void bfs(int x,int y) {
++ans;
vis[x][y] = true;
q[r++] = node{x,y};
while(!(l == r)) {
node t = q[l];
++l;
for (int i = 1; i <= 4; i++) {
int tx =t.x +dx[i],ty = t.y+dy[i];
if (tx < 1 || ty < 1 || tx > n || ty > n) continue;
if (mp[tx][ty] == mp[t.x][t.y]) continue;
if (vis[tx][ty]) continue;
vis[tx][ty] = true;
if (a[tx][ty] != 0) {
ans += a[tx][ty];
continue;
}
++ans;
q[r++] = node{tx,ty};
}
}
}
int main () {
cin >> n >> m;
for (int i = 1; i <= n ;i++) {
for (int j = 1; j <= n; j++) {
char c;
cin >> c;
mp[i][j] =c - '0';
}
}
while (m--) {
int x,y;
cin >> x >> y;
if (a[x][y] != 0 ) {
cout << a[x][y] << endl;
continue;
}
ans = 0;
memset(vis,0,sizeof(vis));
memset(q,0,sizeof(q));
l = 0,r = 0;
bfs(x,y);
for (int i = 0; i <= r; i++) {
if (a[q[i].x][q[i].y] == 0) a[q[i].x][q[i].y] = ans;
}
cout << ans << endl;
}
return 0;
}
by Ascnbeta @ 2024-07-07 15:27:27
80pts TLE on #3 #11
by do_it_tomorrow @ 2024-07-07 15:27:42
@AlwaysSunshine 您不会先预处理吗?
by do_it_tomorrow @ 2024-07-07 15:29:26
其实记录一下已经算出来的答案也可以啊。
by Ascnbeta @ 2024-07-07 15:30:43
@do_it_tomorrow
for (int i = 0; i <= r; i++) {
if (a[q[i].x][q[i].y] == 0) a[q[i].x][q[i].y] = ans;
}
cout << ans << endl;
这是把已经算好的答案存储的代码
预处理真没想到,我去写写
by do_it_tomorrow @ 2024-07-07 15:41:43
@AlwaysSunshine 我的意思是您一边 bfs 一边存答案。
by I_Love_DS @ 2024-07-07 15:53:26
连通块? @AlwaysSunshine
by Ascnbeta @ 2024-07-07 16:10:31
@do_it_tomorrow 我刚开始用预处理来标记当前位置对应的连通块也没过,但我发现删了这一行:
memset(q,0,sizeof(q));
就能过了! 然后我就把我现在这个代码的
memset(vis,0,sizeof(vis));
memset(q,0,sizeof(q));
也删了,发现也不会TLE了
memset
的常数这么大么
by Ascnbeta @ 2024-07-07 16:11:00
相当于memset
导致了TLE