2017年NOIP普及组第三题“chess”题解
作者:岸芷汀兰
题目:
思路:
很遗憾,这道题我没能在考场中写出来,在这里,向我的教练及朋友道歉,我让你们失望了。(QAQ)
50分:普通的dfs。
80分:普通的bfs。
100分:记忆化搜索。
那么记忆化搜索有什么用呢?当前答案大于当前节点的最小花费时,continue。所以要记录每个节点的最小花费。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
const int maxn=105,inf=999999999;
int n,m,a[maxn][maxn],ans=inf,now,dx[]={1,0,-1,0},dy[]={0,1};
int dist[maxn][maxn];
bool vis[maxn][maxn],viss[maxn][maxn];
inline bool check(int x,int y){
if(x<1||x>n||y<1||y>n||viss[x][y])return false;
return true;
}
inline void dfs(int x,int y){
if(now>ans){
return;
}
if(x==n&&y==n){
if(ans>now)ans=now;
return;
}
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(!check(tx,ty))continue;
if(vis[x][y]){//当前有颜色
if(vis[tx][ty]){//下一个有颜色
if(a[x][y]==a[tx][ty]&&now<dist[tx][ty]){
viss[tx][ty]=true;
dist[tx][ty]=now;
dfs(tx,ty);
viss[tx][ty]=false;
}
else if(a[x][y]!=a[tx][ty]&&now+1<dist[tx][ty]){
viss[tx][ty]=true;
dist[tx][ty]=now+1;
now++;
dfs(tx,ty);
now--;
viss[tx][ty]=false;
}
}
else if(now+2<dist[tx][ty]&&(!vis[tx][ty])){//下一个无颜色
a[tx][ty]=a[x][y];
viss[tx][ty]=true;
dist[tx][ty]=now+2;
now+=2;
dfs(tx,ty);
now-=2;
viss[tx][ty]=false;
a[tx][ty]=-1;
}
}
else{//当前无颜色
if(vis[tx][ty]&&(now<dist[tx][ty])){
if(a[tx][ty]==a[x][y]){
int temp=a[x][y];
a[x][y]=-1;
viss[tx][ty]=true;
dist[tx][ty]=now;
dfs(tx,ty);
viss[tx][ty]=false;
a[x][y]=temp;
}
else if((a[tx][ty]!=a[x][y])&&(now+1<dist[tx][ty])){
int temp=a[x][y];
a[x][y]=-1;
viss[tx][ty]=true;
dist[tx][ty]=now+1;
now++;
dfs(tx,ty);
now--;
viss[tx][ty]=false;
a[x][y]=temp;
}
}
else if(!vis[tx][ty]){
continue;
}
}
}
return;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
memset(a,-1,sizeof(a));
n=read();m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dist[i][j]=inf;
}
}
for(int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
a[x][y]=z;
vis[x][y]=true;
}
dfs(1,1);
if(ans==inf)printf("-1");
else printf("%d",ans);
return 0;
}