题解 智力游戏

传送门

它说啥你干啥
BFS 跑了 50 ms

点击查看代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx", "sse")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define fir first
#define sec second
#define ll long long
#define ull unsigned long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n=6, lim;
int typ[100];
bool vis[100];
const ull base=13131;
const int dlt[][2]={{-1,0}, {1,0}, {0,-1}, {0, 1}};
struct pool{
	int a[7][7];
	inline int* operator [] (int t) {return a[t];}
	inline ull hash() {
		ull ans=0;
		for (int i=1; i<=6; ++i)
			for (int j=1; j<=6; ++j)
				ans=ans*base+a[i][j];
		return ans;
	}
	void put() {
		for (int i=1; i<=6; ++i) {
			for (int j=1; j<=6; ++j) cout<<a[i][j]<<' ';
			cout<<endl;
		}
	}
}start;
inline bool inmp(int x, int y) {return x>=1&&x<=6&&y>=1&&y<=6;}

namespace force{
	pair<int, int> fir[100], sec[100];
	struct met{int dis, p, x; char op; ull lst;};
	unordered_map<ull, met> dis;
	queue<pool> q;
	void print(ull u, int all) {
		met tem=dis[u];
		if (!tem.dis) {printf("%d\n", all); return ;}
		print(tem.lst, all);
		printf("%d %c %d\n", tem.p, tem.op, tem.x);
	}
	void solve() {
		dis[start.hash()]={0, 0, 0, 0, 0};
		q.push(start);
		pool u, v;
		while (q.size()) {
			u=q.front(); q.pop();
			// cout<<"---u---"<<endl; u.put(); cout<<endl;
			ull org=u.hash();
			int now=dis[org].dis;
			for (int i=1; i<=lim; ++i) fir[i]=sec[i]={0, 0};
			for (int i=1; i<=6; ++i) {
				for (int j=1; j<=6; ++j) if (u[i][j]) {
					if (!fir[u[i][j]].fir) fir[u[i][j]]={i, j};
					sec[u[i][j]]={i, j};
				}
			}
			for (int i=1; i<=lim; ++i) {
				if (typ[i]==0) {
					pair<int, int> left, right;
					left=fir[i], right=sec[i]; v=u;
					for (int x=1; inmp(right.fir, right.sec+1) && !v[right.fir][right.sec+1]; ++x) {
						v[left.fir][left.sec++]=0;
						v[right.fir][++right.sec]=i;
						ull hash=v.hash();
						if (dis.find(hash)==dis.end()) {
							dis[hash]={now+1, i, x, 'R', org};
							q.push(v);
						}
						if (v[3][5]==1&&v[3][6]==1) {
							// cout<<"---v---"<<endl; v.put(); cout<<endl;
							print(hash, now+1); exit(0);
						}
					}
					left=fir[i], right=sec[i]; v=u;
					for (int x=1; inmp(left.fir, left.sec-1) && !v[left.fir][left.sec-1]; ++x) {
						v[left.fir][--left.sec]=i;
						v[right.fir][right.sec--]=0;
						ull hash=v.hash();
						if (dis.find(hash)==dis.end()) {
							dis[hash]={now+1, i, x, 'L', org};
							q.push(v);
						}
						if (v[3][5]==1&&v[3][6]==1) {
							// cout<<"---v---"<<endl; v.put(); cout<<endl;
							print(hash, now+1); exit(0);
						}
					}
				}
				else {
					pair<int, int> up, down;
					up=fir[i], down=sec[i]; v=u;
					for (int x=1; inmp(up.fir-1, up.sec) && !v[up.fir-1][up.sec]; ++x) {
						v[--up.fir][up.sec]=i;
						v[down.fir--][down.sec]=0;
						ull hash=v.hash();
						if (dis.find(hash)==dis.end()) {
							dis[hash]={now+1, i, x, 'U', org};
							q.push(v);
						}
						if (v[3][5]==1&&v[3][6]==1) {
							// cout<<"---v---"<<endl; v.put(); cout<<endl;
							print(hash, now+1); exit(0);
						}
					}
					up=fir[i], down=sec[i]; v=u;
					for (int x=1; inmp(down.fir+1, down.sec) && !v[down.fir+1][down.sec]; ++x) {
						v[up.fir++][up.sec]=0;
						v[++down.fir][down.sec]=i;
						ull hash=v.hash();
						if (dis.find(hash)==dis.end()) {
							dis[hash]={now+1, i, x, 'D', org};
							q.push(v);
						}
						if (v[3][5]==1&&v[3][6]==1) {
							// cout<<"---v---"<<endl; v.put(); cout<<endl;
							print(hash, now+1); exit(0);
						}
					}
				}
			}
		}
	}
}

signed main()
{
	freopen("game.in", "r", stdin);
	freopen("game.out", "w", stdout);

	for (int i=1; i<=6; ++i)
		for (int j=1; j<=6; ++j)
			lim=max(lim, start[i][j]=read());
	for (int i=1; i<=6; ++i)
		for (int j=1; j<=6; ++j) if (start[i][j] && !vis[start[i][j]]) {
			for (int k=0; k<4; ++k) {
				int x=i+dlt[k][0], y=j+dlt[k][1];
				if (!inmp(x, y) || start[x][y]!=start[i][j]) continue;
				if (k<2) typ[start[i][j]]=1;
				else typ[start[i][j]]=0;
				vis[start[i][j]]=1;
				break;
			}
		}
	// cout<<"typ: "; for (int i=1; i<=lim; ++i) cout<<typ[i]<<' '; cout<<endl;
	if (start[3][5]==1&&start[3][6]==1) {puts("0"); exit(0);}
	force::solve();

	return 0;
}
posted @ 2022-07-06 18:51  Administrator-09  阅读(2)  评论(0编辑  收藏  举报