在一个的,每个格子都有一种给定颜色的方格矩阵上,有一只变色龙在处,他会在这个方格矩阵上移动。
移动规则如下:
- 变色龙只能朝相邻于当前方格的一个方格(上下左右)上移动一格,且不能移出边界。
- 众所周知,变色龙特异的身体会使自己的身体颜色随着环境颜色的变化而变化。所以如果移动到的方格和当前方格的颜色不同,变色龙颜色变化次数会+1,否则颜色变化次数不变。
然而变色龙并不希望能移动的步数最小,它希望颜色的变化次数最小。
它告诉你每个格子的颜色,以及它当前所在的格子,它希望你告诉它从当前格子分别到每个格子的最小颜色变化次数是多少。
错点
b f s bfs bfs 的 p r i o r i t y priority priority_ q u e u e queue queue 优化写假了。
分析
最短路问题。
为什么能使用 d i j dij dij 跑最短路?明显会 T T T 啊!
点数: 2000 × 2000 = 400 , 0000 2000 \times 2000=400,0000 2000×2000=400,0000
边数:小学奥数之等差数列
0 + 4 + ⋯ + 7996 ⏟ 2000 项 = ( 7996 + 0 ) × 2000 ÷ 2 = 7996 × 1000 = 799 , 6000 \begin{matrix}\underbrace{0+4+\cdots+7996}\\2000项\end{matrix}=(7996+0) \times 2000 \div 2=7996 \times 1000=799,6000 0+4+⋯+79962000项=(7996+0)×2000÷2=7996×1000=799,6000
我们知道 d i j dij dij 的复杂度是 O ( n log m ) O(n \log m) O(nlogm) 简单计算一下 log m = log 7996000 ≈ 26 \log m=\log 7996000 \approx 26 logm=log7996000≈26, 26 × 4000000 = 1 , 0400 , 0000 > 1 , 0000 , 0000 26 \times 4000000=1,0400,0000 > 1,0000,0000 26×4000000=1,0400,0000>1,0000,0000
所以显然是会 T T T 掉的~~(除非玄学卡常,比如:等式展开之类的)~~
而 b f s bfs bfs 的期望复杂度是 O ( n + m ) O(n+m) O(n+m) 的。
b f s bfs bfs 大概就是这种写法
q.push((node){xx,yy});
ans[xx][yy]=0;
while(q.size()){
node f=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=f.x+dx[i],y=f.y+dy[i];
if(x>=1&&x<=n&&y>=1&&y<=m){
int as=ans[f.x][f.y];
if(a[x][y]!=a[f.x][f.y])as++;
if(as<ans[x][y])ans[x][y]=as,q.push((node){x,y});
}
}
}
总代码
#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}
struct node{
int x,y;
};
const int MAXN=2000+10;
int n,m,xx,yy,a[MAXN][MAXN],ans[MAXN][MAXN];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
queue<node>q;
int main(){
memset(ans,0x3f,sizeof(ans));
read(n);read(m);read(xx);read(yy);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
read(a[i][j]);
q.push((node){xx,yy});
ans[xx][yy]=0;
while(q.size()){
node f=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=f.x+dx[i],y=f.y+dy[i];
if(x>=1&&x<=n&&y>=1&&y<=m){
int as=ans[f.x][f.y];
if(a[x][y]!=a[f.x][f.y])as++;
if(as<ans[x][y])ans[x][y]=as,q.push((node){x,y});
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cout<<ans[i][j]<<" ";
cout<<endl;
}
return 0;
}