P3956 棋盘

P3956 棋盘

题面:P3956 [NOIP2017 普及组] 棋盘

用深搜

考虑以下几种情况

  1. 当前站在无色格子上,下一步只能前往有色格子

    1. 如果前往的格子的颜色与到达该无色格子的格子颜色相同(这三个格子颜色相同),不花费金币

    2. 如果前往的格子的颜色与到达该无色格子的格子颜色不同(这三个格子有2种颜色),花费 1 金币

  2. 当前站在有色格子上,下一步

    1. 可以前往有色格子:

      1. 前往的格子颜色与当前格子的颜色相同不花费金币

      2. 前往的格子颜色与当前格子的颜色不同花费 1 金币

    2. 可以前往无色格子,花费 2 金币

如果当前格子曾经走过,那么比较这两次花费的金币数,如果本次花费金币更少,那么用当前金币数继续搜索

再就是为了防止出界进行的特判了

struct Node{
	int col;
	bool vis;//是否来过
	int cst;//到这个点的花费
}A[maxM][maxM];

int F[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};

inline int jd1(int a,int b,int c,int d){
	return A[a][b].col == A[c][d].col ? 0 : 1;
}

//dfs(当前格子x,当前格子y,目前花费,上个格子x,上个格子y)
void dfs(int x,int y,int cst,int lx,int ly){
	if(x > m || x < 1 || y > m || y < 1) return;
	if(A[x][y].vis && cst >= A[x][y].cst) return;
	A[x][y].vis = 1;
	A[x][y].cst = cst;
	for(int i = 0;i<4;i++){
		int tx = x + F[i][0];
		int ty = y + F[i][1];
		if(A[x][y].col == 0){//无色格子
			if(A[tx][ty].col == 0) continue;
			dfs(tx,ty,cst+jd1(lx,ly,tx,ty),x,y);//情况1
		}else if(A[tx][ty].col == 0){//有色格子前往无色格子
			dfs(tx,ty,cst+2,x,y);//情况2.2
		}else if(A[x][y].col == A[tx][ty].col){
			dfs(tx,ty,cst,x,y);//情况2.1.1
		}else{
			dfs(tx,ty,cst+1,x,y);//情况2.1.2
		}
	}
}
posted @ 2022-05-05 15:15  Burnling  阅读(75)  评论(0编辑  收藏  举报