在一个的,每个格子都有一种给定颜色的方格矩阵上,有一只变色龙在处,他会在这个方格矩阵上移动。
移动规则如下:
- 变色龙只能朝相邻于当前方格的一个方格(上下左右)上移动一格,且不能移出边界。
- 众所周知,变色龙特异的身体会使自己的身体颜色随着环境颜色的变化而变化。所以如果移动到的方格和当前方格的颜色不同,变色龙颜色变化次数会+1,否则颜色变化次数不变。
然而变色龙并不希望能移动的步数最小,它希望颜色的变化次数最小。
它告诉你每个格子的颜色,以及它当前所在的格子,它希望你告诉它从当前格子分别到每个格子的最小颜色变化次数是多少。
错点
的 _ 优化写假了。
分析
最短路问题。
为什么能使用 跑最短路?明显会 啊!
点数:
边数:小学奥数之等差数列
我们知道 的复杂度是 简单计算一下 ,
所以显然是会 掉的~~(除非玄学卡常,比如:等式展开之类的)~~
而 的期望复杂度是 的。
大概就是这种写法
q.push((node){xx,yy,0});
while(q.size()){
node f=q.top();
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(){
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,0});
while(q.size()){
node f=q.top();
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;
}