首页 > 试题广场 >

棋盘游戏

[编程题]棋盘游戏
  • 热度指数:6151 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
    有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径:     1、只能沿上下左右四个方向移动     2、总代价是没走一步的代价之和     3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积     4、初始状态为1     每走一步,状态按如下公式变化:(走这步的代价%4)+1。

输入描述:
    每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。


输出描述:
    输出最小代价。
示例1

输入

1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 5 5

输出

23
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
using namespace std;
int matrix[10][10];
int x_1,y_1,x_2,y_2;
bool visit[10][10];
int ans ;
int a[] = {-1,1,0,0};
int b[] = {0,0,1,-1};
 
void dfs(int x,int y,int now, int status)
{
    if(x == x_2 && y == y_2)
    {
        ans = min(ans,now);
        return;
    }
    if(now > ans)
    return;
    visit[x][y] = 1;
    
    for(int i = 0 ;i<4;i++)
    {
        int xx = x + a[i],yy = y + b[i];
        if(xx < 0 || xx > 5 || yy < 0 || yy > 5 || visit[xx][yy] == 1)
        continue;
        int cost = matrix[xx][yy] * status;
        int new_status = (cost % 4) + 1;
        dfs(xx,yy,now + cost, new_status);
    }
    visit[x][y] = 0;
}
int main()
{
    while(cin >> matrix[0][0])
    {
        for(int i = 1;i<=5;i++)
        cin >> matrix[0][i];
        memset(visit,0,sizeof(visit));        
        for(int i = 1;i<=5;i++)
        {
            for(int j = 0 ;j<=5;j++)
            {
                cin >> matrix[i][j];        
            }
        }
        ans = 0x3f3f3f3f;
        cin >> x_1 >> y_1 >> x_2 >> y_2 ;
        dfs(x_1,y_1,0,1);
        cout << ans << endl;
    }    
}

发表于 2019-03-04 11:09:37 回复(2)
//Dijkstra
//复杂度O(n^4)
//比二维的棋子多一维状态

#include <stdio.h>

int detax[] = {1,-1,0,0};
int detay[] = {0,0,1,-1};
const int N = 6;
const int MAXP = 100000;
int matrix[N][N];
int price[N][N][4];
int flag[N][N][4];

void dij() {
    for (int i = 0; i < 4 * N * N; i++){
        int ux = -1;
        int uy = -1;
        int uk = -1;
        int priceMin = MAXP;
        for(int jx = 0; jx < N; jx++) 
            for(int jy = 0; jy < N; jy++) 
                for(int jk = 0; jk < 4; jk++)
                    if(flag[jx][jy][jk] == false && price[jx][jy][jk] < priceMin) {
                        ux = jx;
                        uy = jy;
                        uk = jk;
                        priceMin = price[jx][jy][jk];
                    }
        if(ux == -1)    return;
        flag[ux][uy][uk] = true;
        for(int j = 0; j < 4; j++) {
            int vx = ux + detax[j];
            int vy = uy + detay[j];
            if(vx < 0 || vy < 0 || vx >= N || vy >= N)    continue;
            int pr = (uk+1) * matrix[vx][vy];
            int vk = pr % 4;
            if(flag[vx][vy][vk] == true)    continue;
            if(price[vx][vy][vk] < price[ux][uy][uk] + pr)    continue;
            price[vx][vy][vk] = price[ux][uy][uk] + pr;
        }
    }
}

int main() {
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++) {
            scanf("%d",&matrix[i][j]);
            for(int k = 0; k < 4; k++)
                price[i][j][k] = MAXP;
        }
    int sx,sy,ex,ey;
    scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    price[sx][sy][0] = 0;
    dij();
    int ans = MAXP;
    for(int k = 0; k < 4; k++)
        if(price[ex][ey][k] < ans)
            ans = price[ex][ey][k];
    printf("%d",ans);
}


发表于 2020-02-28 20:42:20 回复(1)
似乎是简单的dfs

#include <cstdio>

const int mapSize = 6;
int map[mapSize + 1][mapSize + 1];
bool visited[mapSize + 1][mapSize + 1];
int a, b, c, d;
int ans = 0x3f3f3f3f;
int dir_x[] = {-1, 0, 1, 0};
int dir_y[] = {0, -1, 0, 1};

int min(const int &a, const int &b) {
    return a < b ? a : b;
}

void dfs(const int &x, const int &y,
        const int &curCost, const int &curStatus) {
    if (x == c + 1 && y == d + 1) {
        ans = min(ans, curCost);
        return;
    }
    if (curCost > ans) {
        return;
    }
    //printf("%d, %d\t%d\n", x, y, map[x][y]);
    visited[x][y] = 1;
    for (int i = 0; i < 4; ++i) {
        int next_x = x + dir_x[i];
        int next_y = y + dir_y[i];
        if(next_x < 1 || next_x > 6 || next_y < 1 || next_y > 6 
           || visited[next_x][next_y] == 1) {
            continue;
        }
        int cost = map[next_x][next_y] * curStatus;
        int newStatus = (cost % 4) + 1;
        dfs(next_x, next_y, curCost + cost, newStatus);
    }
    visited[x][y] = 0;
}

int main() {
    for (int i = 1; i <= mapSize; ++i) {
        for (int j = 1; j <= mapSize; ++j) {
            scanf("%d", &map[i][j]);
        }
    }
    scanf("%d%d%d%d", &a, &b, &c, &d);
    dfs(a + 1, b + 1, 0, 1);
    printf("%d\n", ans);
    return 0;
}

发表于 2019-03-13 12:02:02 回复(0)

#include <iostream>



using namespace std;


int map[8][8];

bool visited[8][8];

int res = 0x3f3f3f3f;

//right left up down

int dir[4][2] = {{ 1, 0},

                 {-1, 0},

                 { 0, -1},

                 { 0, 1}};

int s_x, s_y, t_x, t_y;


 /*

规则:

 总代价是没走一步的代价之和

 每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积

 初始状态为1     每走一步,状态按如下公式变化:(走这步的代价%4)+1。

 */


void dfs(int x, int y, int val, int state){

    

    //搜索结束

    if (x == t_x && y == t_y){

        if (val <= res) res = val;

        //cout<<'hhh';

        return;

    }

    //剪枝

    if (val >= res){

        return;

    }

    //记当前节点已访问过

    visited[x][y] = true;

    for (int i=0; i<4; i++){

        int new_x = x + dir[i][0];

        int new_y = y + dir[i][1];

        //cout<<new_x<<' '<<new_y<<endl;

        // 下一个节点可以走 && 未访问过

        if (map[new_x][new_y] != 0 && !visited[new_x][new_y]){

            visited[new_x][new_y] = true;

            int cur_val = map[new_x][new_y] * state;

            dfs(new_x, new_y, val+cur_val, cur_val%4+1);

            visited[new_x][new_y] = false;

        }

    }

}


int main(){

    //8*8棋盘 保证最外围的一层都是0

    for (int i=1; i<=6; i++){

        for (int j=1; j<=6; j++){

            cin >> map[i][j];

        }

    }

    cin >> s_x >> s_y >> t_x >> t_y;

    

    s_x++;

    s_y++;

    t_x++;

    t_y++;

    

    visited[s_x][s_y] = true;

    dfs(s_x, s_y, 0, 1);

    cout<<res;

    

    

}


发表于 2018-07-04 18:01:46 回复(0)
import java.util.Scanner;

public class ChessboardGame {
	private static int[][] dir = {{-1, 0},{1, 0},{0, -1},{0, 1}};//分别为上下左右四个方向
	private static int minCost;//记录最小代价
	public static void dfs(int[][] map, boolean[][] visited, int sum, int status, int startX, int startY, int endX, int endY) {
		if(sum < minCost) {//剪枝, 如果代价sum大于目前最小代价则不必要继续搜索
			if(startX == endX && startY == endY) {//到终点,更新值
				minCost = sum;
			} else {
				for(int i = 0; i < 4; i++) {
					int tempX = startX + dir[i][0];//更新x值
					int tempY = startY + dir[i][1];//更新y值
					
					//合法性判断
					if(tempX >= 0 && tempX < 6 && tempY >= 0 && tempY < 6 && !visited[tempX][tempY]) {
						//代价计算
						int cost = map[tempX][tempY] * status;
						//表示此坐标已访问
						visited[tempX][tempY] = true;
						//sum = sum + cos, status = cost % 4 + 1
						dfs(map, visited, sum + cost, cost % 4 + 1, tempX, tempY, endX, endY);
						//设为未访问进行递归
						visited[tempX][tempY] = false;
					}
				}
			}
		}
	
	}
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		while(cin.hasNext()) {
			int n = cin.nextInt();
			for(int k = 0; k < n; k++) {
				int[][] map = new int[6][6];
				for(int i = 0; i < 6; i++) {
					for(int j = 0; j < 6; j++) {
						map[i][j] = cin.nextInt();
					}
				}
				int startX = cin.nextInt();
				int startY = cin.nextInt();
				int endX = cin.nextInt();
				int endY = cin.nextInt();
				
				boolean[][] visited = new boolean[6][6];
				minCost = Integer.MAX_VALUE;
				//初始时,起始点设为true
				visited[startX][startY] = true;
				dfs(map, visited, 0, 1, startX, startY, endX, endY);
				System.out.println(minCost);
			}
			
		}
		cin.close();
	}

}


发表于 2017-04-04 11:31:30 回复(1)
#include <iostream>
using namespace std;
int total = 0x7fffffff;
int X, Y; // 终点
#define N 6
int p[N][N]; // 棋盘
bool flag[N][N];
int pos[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
void DFS(int s, int c, int x, int y)// 状态s, 代价c, 从<x,y>起
{
    if (flag[x][y]) return;
    if (c > total) return;// 这个剪枝剪得漂亮

    if (x==X && y==Y) {
        if (total == -1) total = c;
        else total = total<c?total:c;
        return;
    }
    if (x < 0 || y < 0 || x >= N || y >= N) return;

    flag[x][y] = true;// 从<x,y>出发,往下深搜不再允许使用<x,y>这个点
    for (int i = 0; i < 4; i ++) {
        int xx = x+pos[i][0], yy = y+pos[i][1];
        int cc = s * p[xx][yy];
        DFS(cc%4+1,c+cc,xx,yy);
    }
    flag[x][y] = false;// 向上层回溯,故而<x,y>还有可能被用到

    return;
}
int main(void)
{

    for (int i = 0; i < N; i ++)
        for (int j = 0; j < N; j ++)
            cin >> p[i][j];
    int x,y;
    cin >> x >> y >> X >> Y;

    DFS(1,0,x,y);

    cout << total << endl;
    return 0;
}
发表于 2019-03-04 14:59:36 回复(5)
一道不错的路径搜索问题。
第一思路是bfs,压入每个点,然后按层次遍历,比dfs要省不少力气。但是带来的问题是:
矩阵部分如下所示:
7 5
6 3
现在从6的点到5的点,很直观的6-3-5是一条更近的路,但是在按照常规bfs思路求解时,如果先访问了6-7-5,则会在这一路径中,将5的visited进行修改,所以根本不会尝试6-3-5的情况。现在在想加一个回溯是否可行,(可能可行,暂未尝试)

由于没有尝试,使用了dfs,一定要注意剪枝,可以省很大力气。同时dfs需要注意回溯的位置。满足要求一定要注意return,递归需要一个出口。

#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <math.h>
#include <cmath>
#include <string>
#include <sstream>
#include <set>
#define INF 0x3f3f3f3f
#pragma warning(disable:4996)
using namespace std;

int dir[][2] = { 0,-1 ,1,0,0,1,-1,0};
vector<vector<int>> num(6, vector<int>(6));
vector<vector<bool>> flag(6, vector<bool>(6, false));
int bestAns = 99999;
int beginx, beginy, endx, endy;

void DFS(int state, int cost, int x, int y) {
	if (x == endx && y == endy) {
		bestAns = min(cost,bestAns);
	}
	if (cost > bestAns)
		return;
	flag[x][y] = true;
	int newx, newy, newstate, newcost;
	for (int i = 0; i < 4; i++) {
		newx = x + dir[i][0];
		newy = y + dir[i][1];
		if (newx < 0 || newx >= 6 || newy < 0 || newy >= 6)
			continue;
		if (flag[newx][newy] == true)
			continue;
		newcost = num[newx][newy] * state;
		//if (newcost+cost > bestAns)
			//continue;
		newstate = (newcost % 4) + 1;
		//flag[newx][newy] = true;
		DFS(newstate, cost + newcost, newx, newy);
	}
	flag[x][y] = false;
	return;
}

int main()
{
	for (int i = 0; i < 6;i++) {
		for (int j = 0; j < 6; j++) {
			cin >> num[i][j];
		}
	}
	cin >> beginx >> beginy >> endx >> endy;
	//flag[beginx][beginy] = true;
	DFS(1, 0, beginx, beginy);
	cout << bestAns << endl;
}



发表于 2019-09-10 11:24:52 回复(0)
我看讨论里面好多人用了visited数组,但是其实题目里并没有明确说不可以踏到同一个点上面,可能有的人会说经历重复的点一定会比不经历重复的点走到终点距离更长,但是很遗憾,这里是有至少一组反例的,该反例是由@安静的美男子plus举出的反例改进而来:
8 9 2 8 10 10
10 7 1 10 10 10
7 1 7 10 10 10
10 10 10 10 10 10
10 10 10 10 10 10
10 10 10 10 10 10
2 1 0 0
在上面这个示例中,如果采用visited数组,最后得出来的值为51,但如果不使用visited数组得出来的值为49,讨论里还有些使用dp的大佬得出来也是49,我这里只用了相对比较简单的暴力递归:
#include <iostream>
#include <vector>
#include <string>
#define ARC 6
 
const int MAX_INT = 400;
const int dxy[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int a, b, c, d;
int mapChess[ARC][ARC];

using namespace std;

void initMap() {
    for (int i = 0; i < ARC; i++) {
        for (int j = 0; j < ARC; j++) {
            cin >> mapChess[i][j];
        }
    }
    cin >> a >> b >> c >> d;
}
 
void dfs_1(int& curMin,int sum,int state,int cura,int curb){
    if (cura == c && curb == d) {
        if (sum < curMin)
            curMin = sum;
        return;
    }
    for (int i = 0; i < 4; i++) {
        int nexta = cura + dxy[i][0];
        int nextb = curb + dxy[i][1];
        if (nexta >= 0 && nexta< ARC && nextb >= 0 && nextb < ARC) {
            if (sum + state * mapChess[nexta][nextb] < curMin) {
                dfs_1(curMin, sum + state * mapChess[nexta][nextb], state * mapChess[nexta][nextb]%4+1, nexta, nextb);
            }
        }
    }
}
 
int main() {
    initMap();
    int curMin = MAX_INT;
    dfs_1(curMin, 0, 1, a, b);
    cout << curMin << endl;
}


发表于 2022-03-11 17:32:15 回复(0)
#include<bits/stdc++.h>//动态规划解法
using namespace std;
int a[6][6];
int sign(int a,int b){
    if (a>b)return -1;
    else if(a<b)return 1;
    else return 0;
}
int opt(int x1,int y1,int x2,int y2,int stat){
    int p1,p2,stat1,stat2;
    int sig1=sign(x1,x2),sig2=sign(y1,y2);
    p1=stat*a[x1+sig1][y1];stat1=p1%4+1;
    p2=stat*a[x1][y1+sig2];stat2=p2%4+1;
    if(sig1==0&&sig2==0)return 0;
    if(sig1!=0&&sig2!=0){        
        return min(p1+opt(x1+sig1,y1,x2,y2,stat1),p2+opt(x1,y1+sig2,x2,y2,stat2));
    }
    if(sig1==0) return p2+opt(x1,y1+sig2,x2,y2,stat2);
    else return p1+opt(x1+sig1,y1,x2,y2,stat1);
    
}
int main(){
    int a1,b,c,d;
    for(int i=0;i<6;i++){
        for(int j=0;j<6;j++){
        cin>>a[i][j];
        }
    }
    cin>>a1>>b>>c>>d;
    cout<<opt(a1,b,c,d,1);
    return 0;
}

编辑于 2020-01-17 22:04:52 回复(2)
#include<bits/stdc++.h>
using namespace std;
//搜索的上下左右四个方向
int direction[4][2]={
    {
        0,1
    },//向左
    {
        0,-1
    },//向右
    {
        1,0
    },//向下
    {
        -1,0
    }//向上
};

int bx,by;//搜索的起点
int ex,ey;//搜索的终点

int bestcost=INT_MAX;//最小代价

int matrix[6][6]={0};//棋盘

int hadvisit[6][6]={0};//标记是否访问

//通过深度搜索寻找最小代价
void dfs(int x,int y,int status,int cost)
{
    //(x,y)是当前访问节点
    //status是题目中规定的状态
    //cost是当前代价
    if(x==ex&&y==ey)
    {
        //已经到达了终点
        bestcost=min(bestcost,cost);
        //最小代价是当前代价和以前总代价的最小值

    }

    if(cost>bestcost)
    {
        //搜索当中当前代价已经大于了以前的代价值
        //返回,不用继续搜索
        return ;
    }

    hadvisit[x][y]=1;//标记当前节点已经被访问

    //题目规定只能向四个方向进行搜索
    for(int i=0;i<4;i++)
    {
        int nx=x+direction[i][0];//更新方向
        int ny=y+direction[i][1];//更新方向

        //新方向在棋盘内,并且没有被访问
        if((nx>=0&&nx<6&&ny>=0&&ny<6)&&(hadvisit[nx][ny]==0))
        {
            //新的代价
            int nc=matrix[nx][ny]*status;
            //新的状态
            int ns=(nc%4)+1;
            //进行搜索试探
            hadvisit[nx][ny]=1;
            dfs(nx,ny,ns,nc+cost);
            //试探失败,清除标记便于下次试探
            hadvisit[nx][ny]=0;
        }
        else
        //继续寻找方向
        continue;
    }
}

int main()
{
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    scanf("%d%d%d%d",&bx,&by,&ex,&ey);
    dfs(bx,by,1,0);
    printf("%d\n",bestcost);
    return 0;
}

发表于 2020-08-12 19:47:04 回复(0)
有没有大佬帮忙看一下这个为什么会超时啊
#include<iostream>
#include<algorithm>
#include<limits.h>
using namespace std;
int chess[6][6];
int minCost = INT_MAX;

//深度优先遍历棋盘
void DFS(int curx, int cury, int endx, int endy, int visit[6][6],int curCost,int state) {
    //判断当前是否已经到达终点
    if (curx == endx && cury == endy)
        minCost = min(curCost, minCost);
    else {
        if (curCost < minCost) {    //如果当前代价已经超过了目前的最小代价,则后面的工作不用做了,节省时间
            visit[curx][cury] = 1;  //表示已经被访问过了
            //走上下左右四个位置
            //上
            if (cury != 0 && visit[curx][cury - 1] == 0)
                DFS(curx, cury - 1, endx, endy, visit, curCost + state * chess[curx][cury - 1], (state*chess[curx][cury - 1]) % 4 + 1);
            //下
            if (cury != 5 && visit[curx][cury + 1] == 0)
                DFS(curx, cury + 1, endx, endy, visit, curCost + state * chess[curx][cury + 1], (state*chess[curx][cury + 1]) % 4 + 1);
            //左
            if (curx != 0 && visit[curx - 1][cury] == 0)
                DFS(curx - 1, cury, endx, endy, visit, curCost + state * chess[curx - 1][cury], (state*chess[curx - 1][cury]) % 4 + 1);
            //右
            if (curx != 5 && visit[curx + 1][cury] == 0)
                DFS(curx + 1, cury, endx, endy, visit, curCost + state * chess[curx + 1][cury], (state*chess[curx + 1][cury]) % 4 + 1);
            visit[curx][cury] = 0;
        }

    }
}
int main() {
    int startx, starty, endx, endy;

    while (true) {
        minCost = INT_MAX;
        int visited[6][6] = { 0 };
        for (int i = 0; i < 6; i++)
            for (int j = 0; j < 6; j++)
                cin >> chess[i][j];
        cin >> startx >> starty >> endx >> endy;

        DFS(startx, starty, endx, endy, visited, 0, 1);
        cout << minCost << endl;
    }
    return 0;
}
发表于 2019-03-10 10:54:16 回复(1)
简单的深度优先搜索
#include <iostream>
using namespace std;

int matrix[6][6];
int ans=10000;
int visit[6][6];


void dfs(int x0, int y0, int x1, int y1,int zt,int cost){
    if(visit[x0][y0]) return;
    if(x0==x1 && y0==y1){
        if(ans>cost) ans=cost;
        return;
    }
    visit[x0][y0]=1;
    if(x0+1<6) 
        dfs(x0+1,y0,x1,y1,zt*matrix[x0+1][y0]%4+1,cost+zt*matrix[x0+1][y0]);
    if(x0-1>=0) 
        dfs(x0-1,y0,x1,y1,zt*matrix[x0-1][y0]%4+1,cost+zt*matrix[x0-1][y0]);
    if(y0+1<6) 
        dfs(x0,y0+1,x1,y1,zt*matrix[x0][y0+1]%4+1,cost+zt*matrix[x0][y0+1]);
    if(y0-1>=0) 
        dfs(x0,y0-1,x1,y1,zt*matrix[x0][y0-1]%4+1,cost+zt*matrix[x0][y0-1]);
    visit[x0][y0]=0;
}

int main() {
    int x0,y0,x1,y1;
    for(int i=0;i<6;i++)
        for(int j=0;j<6;j++)
            cin >> matrix[i][j];
    cin >> x0 >> y0 >> x1 >> y1;
    dfs(x0,y0,x1,y1,1,0);
    cout << ans << endl;
}
// 64 位输出请用 printf("%lld")


发表于 2024-03-12 11:57:47 回复(0)
#include <climits>
#include <iostream>
using namespace std;
int minprice=INT_MAX;
int x1,y1,x2,y2;
int used[6][6]={0};
int res[6][6];
class Solution{
public:
    void dfs(int x,int y,int state,int min){
        if(x<0||x>=6||y<0||y>=6||used[x][y])return ;
        if(min>minprice)return ;
        if(x==x2&&y==y2){
            if(min<minprice)minprice=min;
            return ;
        }
       
        else{
            used[x][y]=1;
            int cost;
            cost=res[x][y]*state;
            state=(cost%4)+1;
            min+=cost;
            dfs(x+1,y,state,min);
             //used[x][y]=0;
            dfs(x-1,y,state,min);
            //used[x][y]=0;
            dfs(x,y+1,state,min);
            //used[x][y]=0;
            dfs(x,y-1,state,min);
            used[x][y]=0;
        }
       
    }
};
int main() {
    int i,j;
    Solution m;
    for(i=0;i<6;i++){
        for(j=0;j<6;j++){
            cin>>res[i][j];
        }
    }
    cin>>x1>>y1>>x2>>y2;
    m.dfs(x1, y1, 1, 0);
    cout<<minprice<<endl;
}
// 64 位输出请用 printf("%lld")
编辑于 2024-03-07 17:44:30 回复(1)
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int point[6][6];
int visit[6][6]={0};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int m,n;//m,n是终点
int ans=1000000;
void dfs(int x,int y,int count,int  situ)//count为总花费,situ为状态
{  
    if(x==m&y==n)
    {ans=min(ans,count);
    return;}
    if(count>ans)
    return;
    visit[x][y]=1;//访问当前节点。
    for(int i=0;i<4;i++)
    {  
       
         
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx>=6||nx<0||ny>=6||ny<0)
                 continue;
            if(visit[nx][ny]==0){
            dfs(nx,ny,count+point[nx][ny]*situ,(point[nx][ny]*situ)%4+1);
            visit[nx][ny]=0;//回溯
            }
            else{
                continue;
            }
       
    }
}
//x,y是当前坐标,count是花费
int main() {
    int a,b;
    for(int i=0;i<6;i++)
    {for(int j=0;j<6;j++)
    {
        scanf("%d",&point[i][j]);
    }
    }
    scanf("%d %d %d %d",&a,&b,&m,&n);
    dfs(a,b,0,1);
    printf("%d",ans);
   return 0;

 
   
}
发表于 2023-03-26 18:13:40 回复(0)
//剪枝很重要
#include "stdio.h"
#include "climits"
#include "algorithm"
using namespace std;
int array[6][6];
bool isVisit[6][6];//false为未访问,true为访问
int direction[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};
int sx,sy,ex,ey;
int res = INT_MAX;

void dfs(int x,int y,int status,int cost){
    if(x == ex && y == ey){
        res = min(cost,res);
        return;
    }
    if(cost > res)
        return;//剪枝
    isVisit[x][y] = true;
    for (int i = 0; i < 4; ++i) {
        int next_x = direction[i][0]+x;
        int next_y = direction[i][1]+y;
        if(next_x >= 0 && next_x < 6 && next_y >= 0 && next_y < 6 && isVisit[next_x][next_y] == false){
            int nc = array[next_x][next_y]*status;
            int ns = nc%4+1;
            dfs(next_x,next_y,ns,nc+cost);
            isVisit[next_x][next_y] = false;
        }
    }
}

int main(){
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            scanf("%d",&array[i][j]);
            isVisit[i][j] = false;
        }
    }
    scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    dfs(sx,sy,1,0);
    printf("%d",res);
}
发表于 2023-03-13 21:27:31 回复(0)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <cmath>
#include <queue>
#include <limits.h>
#include<float.h>

using namespace std;
typedef long long LL;

int a[7][7];
int c,d;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
bool s[7][7];
int res=INT32_MAX;

void dfs(int x,int y,int last,int st)
{
    if(x==c&&y==d) 
    {
        res=min(res,last);
    }
    if(last>=res) return;

    for(int i=0;i<4;i++)
    {
        int x1=x+dir[i][0],y1=y+dir[i][1];
        if(x1>=0&&x1<6&&y1>=0&&y1<6&&!s[x1][y1])
        {
            s[x1][y1]=true;
            dfs(x1,y1,last+st*a[x1][y1],st*a[x1][y1]%4+1);
            s[x1][y1]=false;
        }
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    for(int i=0;i<6;i++)
        for(int j=0;j<6;j++)
            cin>>a[i][j];
    
    int a,b;
    cin>>a>>b>>c>>d;
    dfs(a,b,0,1);
    cout<<res<<endl;
    return 0;
}



发表于 2022-09-17 17:39:11 回复(0)
我用的记忆化搜索,但不能全部通过,头痛。。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int a[10][10];
int p[10][10];
int x1, x2, y1, y2;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

int search(int x, int y, int state)
{
	if (x == x2 && y == y2)
	{
		p[x][y] = 0;
		return 0;
	}
	if (p[x][y] != -1) return p[x][y];
	
	int &ans = p[x][y];
	ans = 0x3f3f3f3f;
	for (int i = 0; i < 4; i ++)
	{
		int nx = x + dx[i], ny = y + dy[i];
		if (nx >= 0 && nx < 6 && ny >= 0 && ny < 6)
		{
			int price = state * a[nx][ny];
			ans = min(ans, price + search(nx, ny, (price % 4) + 1));
		}
	}
	return ans;
}

int main()
{
	memset(p, -1, sizeof p);
	for (int i = 0; i < 6; i ++)
	{
		for (int j = 0; j < 6; j ++)
			cin >> a[i][j];
	}

	scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
	
	int res = search(x1, y1, 1);
	
	printf("%d\n", res);
	
	return 0;
}

发表于 2022-03-22 21:17:38 回复(0)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>

using namespace std;

int matrix[6][6];
bool visited[6][6];
int pos[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
vector<int> v;

void dfs(int x1, int y1, int x2, int y2, int statue, int cost){
    if(x1 == x2 && y1 == y2) v.push_back(cost);
    else{
        for(int i = 0; i < 4; i++){
            int nx = x1 + pos[i][0];
            int ny = y1 + pos[i][1];
            if(nx < 0 || nx >= 6 || ny < 0 || ny >= 6 || visited[nx][ny]) continue;
            int c = matrix[nx][ny] * statue;
            int s = c % 4 + 1;
            visited[nx][ny] = true;
            dfs(nx, ny, x2, y2, s, cost + c);
            visited[nx][ny] = false;
        }
    }
}

int main(){
    while(scanf("%d", &matrix[0][0]) != EOF){
        for(int i = 0; i < 6; i++){
            for(int j = 0; j < 6; j++){
                if(i == 0 && j == 0) continue;
                else scanf("%d", &matrix[i][j]);
            }
        }
        int x1, y1, x2, y2;
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        memset(visited, false, sizeof(visited));
        visited[x1][y1] = true;
        dfs(x1, y1, x2, y2, 1, 0);
        sort(v.begin(), v.end());
        printf("%d\n", v[0]);
    }
    return 0;
}
发表于 2022-03-02 15:00:40 回复(0)
#include <iostream>
#include <algorithm>
#include <climits>

using namespace std;

int panel[10][10];
int mincost = INT_MAX;
int a, b, c, d;
int dirx[4] = {0, 1, 0, -1};
int diry[4] = {1, 0, -1, 0};
bool flag[10][10];

void dfs(int x, int y, int cursta, int curcost) {
    if (x == c && y == d) {
        mincost = min(mincost, curcost);
        return;
    }
    for (int i = 0; i < 4; i++) {
        int tx = x + dirx[i];
        int ty = y + diry[i];
        if (tx >= 0 && tx < 6 && ty >= 0 && ty < 6 && flag[tx][ty] == false) {
            int cost = panel[tx][ty] * cursta;
            int state = cost % 4 + 1;
            if (curcost + cost < mincost) {
                flag[tx][ty] = true;
                dfs(tx, ty, state, curcost + cost);   
                flag[tx][ty] = false;
            }
        }
    }
}

int main() {    
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            cin >> panel[i][j];
        }
    }   
    cin >> a >> b >> c >> d;
    flag[a][b] = true;
    dfs(a, b, 1, 0);
    cout << mincost << endl;

    return 0;
}
发表于 2022-02-26 18:32:39 回复(0)

动态规划+深度搜索

#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;
const int INF = 1 << 30;
// 纯动态规划解
int dp[6][6][5];
int a[6][6];
void initial()
{
    for (int i = 0; i < 6; i++)
        for (int j = 0; j < 6; j++)
            for (int k = 1; k <= 4; k++)
                dp[i][j][k] = INF;
}
bool update(int x, int y,int k,int d) // 点坐标x,y,上一步的状态,上一步的代价
{
    if (x < 0 || x >= 6 || y < 0 || y >= 6) return false;
    int cost = k * a[x][y]; // 上一步的状态乘以该位置的数值
    int pos = cost % 4 + 1;
    if (dp[x][y][pos] > d + cost)
    {
        dp[x][y][pos] = d + cost;
        return true;
    }
    return false;
}
void guihua(int x, int y,int k,int d)
{
    if (update(x - 1, y, k, d)) guihua(x - 1, y, k * a[x - 1][y] % 4 + 1, d + k * a[x - 1][y]);
    if (update(x + 1, y, k, d)) guihua(x + 1, y, k * a[x + 1][y] % 4 + 1, d + k * a[x + 1][y]);
    if (update(x, y - 1, k, d)) guihua(x, y - 1, k * a[x][y - 1] % 4 + 1, d + k * a[x][y - 1]);
    if (update(x, y + 1, k, d)) guihua(x, y + 1, k * a[x][y + 1] % 4 + 1, d + k * a[x][y + 1]);
}

int main()
{
    for (int i = 0; i < 6; i++)
        for (int j = 0; j < 6; j++)
            cin >> a[i][j];
    int sx, sy, ex, ey;
    cin >> sx >> sy >> ex >> ey;
    initial();
    dp[sx][sy][1] = 0;
    guihua(sx, sy, 1, 0);
    int m = dp[ex][ey][1];
    for (int i = 2; i <= 4; i++)
        m = min(m, dp[ex][ey][i]);
    cout << m << endl;
}
发表于 2021-03-22 08:37:04 回复(0)

问题信息

难度:
40条回答 6459浏览

热门推荐

通过挑战的用户

查看代码