UVa810 A Dicey Problem 筛子难题

将一个筛子放在M*N的地图上,每次翻滚前翻滚后的位置的点数必须要与翻滚前筛子的上面的点数相同,给定起点,找出一条可循路径,返回起点。

这题好像没有强调最短路径,可以用dfs做,我TL了,用的bfs,可能是输出路径调用了栈,也可能是bfs判断条件多了。

以后有好的想法再改吧

#include<iostream>
#include <string>
#include <string.h>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
const int MAXN = 10 + 5;
struct Point {
	int x, y;
	int face, top;
	Point(){}
	Point(int _x,int _y):x(_x),y(_y){}
	Point(int _x,int _y,int _face,int _top):x(_x),y(_y),face(_face),top(_top){}
	ostream operator<<(const Point &u) {
		cout << "(" << u.x << u.y<<")";
	}
	bool operator==(const Point &u) {
		return x == u.x&&y == u.y;
	}
};
struct Node {
	int x, y; int face, top;
	Node(){}
	Node(int _x,int _y,int _face,int _top):x(_x),y(_y),face(_face),top(_top){}
}mr[MAXN][MAXN][MAXN][MAXN];
int r, c;
int mp[MAXN][MAXN];
int totop[MAXN][MAXN];
int vis[MAXN][MAXN][MAXN][MAXN];
//vector<Point> lw[MAXN*MAXN];
int main()
{
	string s;
	totop[1][2] = 4; totop[1][3]= 2; totop[1][4] = 5; totop[1][5] = 3;
	totop[2][1] = 3; totop[2][3]= 6; totop[2][4] = 1; totop[2][6] = 4;
	totop[3][1] = 5; totop[3][2]= 1; totop[3][5] = 6; totop[3][6] = 2;
	totop[4][1] = 2; totop[4][2]= 6; totop[4][5] = 1; totop[4][6] = 5;
	totop[5][1] = 4; totop[5][3]= 1; totop[5][4] = 6; totop[5][6] = 3;
	totop[6][2] = 3; totop[6][3]= 5; totop[6][4] = 2; totop[6][5] = 4;
	while (cin >> s && s != "END") {
		memset(vis, 0, sizeof(vis));
		memset(mp, 0, sizeof(mp));
		//memset(totop, 0, sizeof(totop));
		cin >> r>> c; Point startpos;
		cin >> startpos.x >> startpos.y;
		cin >> startpos.top >> startpos.face;
		Point endpos = startpos;
		for (int i = 1; i <= r; i++) {
			for (int j = 1; j <= c; j++) {
				cin >> mp[i][j];
			}
		}
		queue<Point>route;
		route.push(startpos);
		vis[startpos.x][startpos.y][startpos.face][startpos.top] = 1;
		bool ispack = false;
		while (!route.empty()) {
			Point nowpos = route.front();
			vis[nowpos.x][nowpos.y][nowpos.face][nowpos.top] = 1;
			route.pop();
			if (nowpos.x > 1&&nowpos.x<=r ) {
				if (mp[nowpos.x - 1][nowpos.y]&&!vis[nowpos.x - 1][nowpos.y][7 - nowpos.top][nowpos.face] && (nowpos.top == mp[nowpos.x - 1][nowpos.y] || mp[nowpos.x - 1][nowpos.y] == -1)) {
					route.push(Point(nowpos.x - 1, nowpos.y, 7 - nowpos.top, nowpos.face)); mr[nowpos.x - 1][nowpos.y][7 - nowpos.top][nowpos.face] = Node(nowpos.x, nowpos.y,nowpos.face,nowpos.top);
					if (nowpos.x - 1== startpos.x&&nowpos.y==startpos.y)break;
				}
			}
			if (nowpos.x >= 1 && nowpos.x < r) {
				if (mp[nowpos.x + 1][nowpos.y]&&!vis[nowpos.x + 1][nowpos.y][7 - nowpos.face][nowpos.top] && (nowpos.top == mp[nowpos.x + 1][nowpos.y] || mp[nowpos.x + 1][nowpos.y] == -1)) {
					route.push(Point(nowpos.x + 1, nowpos.y, nowpos.top,7 - nowpos.face)); mr[nowpos.x + 1][nowpos.y][nowpos.top][7 - nowpos.face] = Node(nowpos.x, nowpos.y, nowpos.face, nowpos.top);
					if (nowpos.x +1 == startpos.x&&nowpos.y == startpos.y)break;
				}
			}
			if (nowpos.y > 1 && nowpos.y <= c) {
				if (mp[nowpos.x][nowpos.y - 1] &&!vis[nowpos.x][nowpos.y - 1][nowpos.face][totop[nowpos.face][nowpos.top]] && (nowpos.top == mp[nowpos.x][nowpos.y - 1] || mp[nowpos.x ][nowpos.y-1] == -1)) {
					route.push(Point(nowpos.x, nowpos.y - 1, nowpos.face, totop[nowpos.face][nowpos.top])); mr[nowpos.x ][nowpos.y-1][nowpos.face][totop[nowpos.face][nowpos.top]] = Node(nowpos.x, nowpos.y, nowpos.face, nowpos.top);
					if (nowpos.x == startpos.x&&nowpos.y-1 == startpos.y)break;
				}		
			}
			if (nowpos.y >= 1 && nowpos.y < c) {
				if (mp[nowpos.x][nowpos.y + 1]&&!vis[nowpos.x][nowpos.y + 1][nowpos.face][totop[nowpos.top][nowpos.face]] && (nowpos.top == mp[nowpos.x][nowpos.y + 1] || mp[nowpos.x ][nowpos.y+1] == -1)) {
					route.push(Point(nowpos.x, nowpos.y + 1, nowpos.face, totop[nowpos.top][nowpos.face])); mr[nowpos.x][nowpos.y + 1][nowpos.face][totop[nowpos.top][nowpos.face]] = Node(nowpos.x, nowpos.y, nowpos.face, nowpos.top);
					if (nowpos.x  == startpos.x&&nowpos.y+1 == startpos.y)break;
				}
			}
			//next: report the route
		}
		if (route.empty())cout <<s<<endl<< "  No Solution Possible" << endl;
		else {
			Node e = mr[route.front().x][route.front().y][route.front().face][route.front().top];
			stack<Node> st;
			//	cout << "(" << endpos.x << "," << endpos.y << ")";
			st.push(Node(endpos.x, endpos.y, endpos.face, endpos.top));
			while (e.x != endpos.x || e.y != endpos.y) {
				//cout << "(" << e.x << "," << e.y << ")";
				st.push(e);
				e = mr[e.x][e.y][e.face][e.top];
			}
			st.push(Node(endpos.x, endpos.y, endpos.face, endpos.top));
			//cout << "(" << endpos.x << "," << endpos.y << ")";
			cout << s << endl<<"  ";
			int i = 0;
			while (!st.empty()) {
				Node r = st.top();
				cout << "(" << r.x << "," << r.y << ")"; i++;
				st.pop();
				if (i % 9==0&&!st.empty()) { cout << endl << "  "; }
			}
			cout << endl;
		}
	}
	//system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值