HDU 4801 2013 Changsha Regional Pocket Cube[大模拟]

题意:

2×2的魔方,给出初始状态,问7步之内最多能有几个面相同


本来是道大水题

但是,,,

心酸啊

一开始直接得到状态的hash,用bool vis来bfs,但是wa了,我以为不行,然后又用结构体哈希vis来bfs,然后还是WA,结果发现,,,魔方有6种转法,我只想到了4种。。。

然后改成6种,各种T各种MLE,再改回bool vis才过了

算了下,6^7=24W,然后我bool开的是999997,应该会很大冲突,但是好像没什么影响,加到900W大小的bool也可以(基于这点我才想到用结构体哈希)。。。


也算是深深了解到了bfs的弊端,毕竟你没用递归,时间上是很快,但是,慢的是你要存储已经出现过的状态,如果状态不能状压往往会很难弄,毕竟用bool 害怕地址冲突,用结构体哈希vecotor又太慢,这种情况下,还是dfs比较明智

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <climits>
using namespace std;
#define pb push_back
int N;
const int MOD=9199997;
struct MOFANG;
bool vis[MOD];
struct MOFANG{
	int m[24];
	int step;
	MOFANG(){memset(m,0,sizeof(m));step=0;}
	bool operator==(MOFANG s){
		bool all_same=true;
		for(int i=0;i<24 && all_same;i++){
			if(m[i]!=s.m[i]) all_same=false;
		}
		return all_same;
	}
	int key(){
		int sum=0;
		for(int i=0;i<24;i++){
			sum=(sum*6+m[i])%MOD;
		}
		return sum%MOD;
	}
	int same_face(){
		int sum=0;
		if(m[6]==m[7] && m[7]==m[13] && m[13]==m[12]) sum++;
		if(m[0]==m[1] && m[1]==m[3] && m[3]==m[2]) sum++;
		if(m[8]==m[9] && m[9]==m[15] && m[15]==m[14]) sum++;
		if(m[16]==m[17] && m[17]==m[19] && m[19]==m[18]) sum++;
		if(m[20]==m[21] && m[21]==m[23] && m[23]==m[22]) sum++;
		if(m[4]==m[5] && m[5]==m[11] && m[11]==m[10]) sum++;
		return sum;
	}
	void left_up(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[20];
		tmp[2]=m[22];
		tmp[6]=m[0];
		tmp[12]=m[2];
		tmp[16]=m[6];
		tmp[18]=m[12];
		tmp[20]=m[16];
		tmp[22]=m[18];
		tmp[4]=m[10];
		tmp[5]=m[4];
		tmp[10]=m[11];
		tmp[11]=m[5];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void left_down(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[6];
		tmp[2]=m[12];
		tmp[6]=m[16];
		tmp[12]=m[18];
		tmp[16]=m[20];
		tmp[18]=m[22];
		tmp[20]=m[0];
		tmp[22]=m[2];
		tmp[4]=m[5];
		tmp[5]=m[11];
		tmp[10]=m[4];
		tmp[11]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_right(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[8];
		tmp[3]=m[14];
		tmp[5]=m[3];
		tmp[6]=m[7];
		tmp[7]=m[13];
		tmp[8]=m[17];
		tmp[11]=m[2];
		tmp[12]=m[6];
		tmp[13]=m[12];
		tmp[14]=m[16];
		tmp[16]=m[5];
		tmp[17]=m[11];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_left(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[11];
		tmp[3]=m[5];
		tmp[5]=m[16];
		tmp[6]=m[12];
		tmp[7]=m[6];
		tmp[8]=m[2];
		tmp[11]=m[17];
		tmp[12]=m[13];
		tmp[13]=m[7];
		tmp[14]=m[3];
		tmp[16]=m[14];
		tmp[17]=m[8];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_right(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[12];
		tmp[11]=m[13];
		tmp[12]=m[14];
		tmp[13]=m[15];
		tmp[14]=m[21];
		tmp[15]=m[20];
		tmp[16]=m[17];
		tmp[17]=m[19];
		tmp[18]=m[16];
		tmp[19]=m[18];
		tmp[20]=m[11];
		tmp[21]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_left(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[21];
		tmp[11]=m[20];
		tmp[12]=m[10];
		tmp[13]=m[11];
		tmp[14]=m[12];
		tmp[15]=m[13];
		tmp[16]=m[18];
		tmp[17]=m[16];
		tmp[18]=m[19];
		tmp[19]=m[17];
		tmp[20]=m[15];
		tmp[21]=m[14];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	/*bool is_in(){
                int key_v=key();
                if(vis[key_v].size()==0){
                        vis[key_v].pb(*this);
                        return false;
                }else{
                        for(int i=0;i<vis[key_v].size();i++){
                                if(vis[key_v][i]==*this) return true;
                        }
                        vis[key_v].pb(*this);
                        return false;
                }
	}*/
}st,que[199999];

int ans=0;
void bfs(){
	vis[st.key()]=true;
	int head=0,tail=0;
	que[tail++]=st;
	while(head<tail){
		MOFANG now=que[head++];
		if(now.step>N) continue;
		ans=max(ans,now.same_face());
		if(now.step==N) continue;
		MOFANG tmp=now;
		tmp.step++;
		tmp.left_up();
		int key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
		tmp=now;
		tmp.step++;
		tmp.left_down();
		key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
		tmp=now;
		tmp.step++;
		tmp.down_right();
		key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
		tmp=now;
		tmp.step++;
		tmp.down_left();
		key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
		tmp=now;
		tmp.step++;
		tmp.front_right();
		key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
		tmp=now;
		tmp.step++;
		tmp.front_left();
		key=tmp.key();
		if(!vis[key]){
                        vis[key]=true;
			que[tail++]=tmp;
		}
	}
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif
	while(scanf("%d",&N)!=EOF){
		ans=0;
                memset(vis,0,sizeof(vis));
		//for(int i=0;i<MOD;i++) vis[i].clear();
		for(int i=0;i<24;i++)
			scanf("%d",&st.m[i]);
		bfs();
		printf("%d\n",ans);
	}
}


,,,dfs真好写啊,看来以后没有最短之类的需求的话还是用dfs写,也不用que,也不用数组记录出没出现过

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <climits>
using namespace std;
#define pb push_back
int N;
const int MOD=9199997;
struct MOFANG;
bool vis[MOD];
struct MOFANG{
	int m[24];
	int step;
	MOFANG(){memset(m,0,sizeof(m));step=0;}
	bool operator==(MOFANG s){
		bool all_same=true;
		for(int i=0;i<24 && all_same;i++){
			if(m[i]!=s.m[i]) all_same=false;
		}
		return all_same;
	}
	int key(){
		int sum=0;
		for(int i=0;i<24;i++){
			sum=(sum*6+m[i])%MOD;
		}
		return sum%MOD;
	}
	int same_face(){
		int sum=0;
		if(m[6]==m[7] && m[7]==m[13] && m[13]==m[12]) sum++;
		if(m[0]==m[1] && m[1]==m[3] && m[3]==m[2]) sum++;
		if(m[8]==m[9] && m[9]==m[15] && m[15]==m[14]) sum++;
		if(m[16]==m[17] && m[17]==m[19] && m[19]==m[18]) sum++;
		if(m[20]==m[21] && m[21]==m[23] && m[23]==m[22]) sum++;
		if(m[4]==m[5] && m[5]==m[11] && m[11]==m[10]) sum++;
		return sum;
	}
	void left_up(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[20];
		tmp[2]=m[22];
		tmp[6]=m[0];
		tmp[12]=m[2];
		tmp[16]=m[6];
		tmp[18]=m[12];
		tmp[20]=m[16];
		tmp[22]=m[18];
		tmp[4]=m[10];
		tmp[5]=m[4];
		tmp[10]=m[11];
		tmp[11]=m[5];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void left_down(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[6];
		tmp[2]=m[12];
		tmp[6]=m[16];
		tmp[12]=m[18];
		tmp[16]=m[20];
		tmp[18]=m[22];
		tmp[20]=m[0];
		tmp[22]=m[2];
		tmp[4]=m[5];
		tmp[5]=m[11];
		tmp[10]=m[4];
		tmp[11]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_right(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[8];
		tmp[3]=m[14];
		tmp[5]=m[3];
		tmp[6]=m[7];
		tmp[7]=m[13];
		tmp[8]=m[17];
		tmp[11]=m[2];
		tmp[12]=m[6];
		tmp[13]=m[12];
		tmp[14]=m[16];
		tmp[16]=m[5];
		tmp[17]=m[11];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_left(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[11];
		tmp[3]=m[5];
		tmp[5]=m[16];
		tmp[6]=m[12];
		tmp[7]=m[6];
		tmp[8]=m[2];
		tmp[11]=m[17];
		tmp[12]=m[13];
		tmp[13]=m[7];
		tmp[14]=m[3];
		tmp[16]=m[14];
		tmp[17]=m[8];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_right(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[12];
		tmp[11]=m[13];
		tmp[12]=m[14];
		tmp[13]=m[15];
		tmp[14]=m[21];
		tmp[15]=m[20];
		tmp[16]=m[17];
		tmp[17]=m[19];
		tmp[18]=m[16];
		tmp[19]=m[18];
		tmp[20]=m[11];
		tmp[21]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_left(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[21];
		tmp[11]=m[20];
		tmp[12]=m[10];
		tmp[13]=m[11];
		tmp[14]=m[12];
		tmp[15]=m[13];
		tmp[16]=m[18];
		tmp[17]=m[16];
		tmp[18]=m[19];
		tmp[19]=m[17];
		tmp[20]=m[15];
		tmp[21]=m[14];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	/*bool is_in(){
                int key_v=key();
                if(vis[key_v].size()==0){
                        vis[key_v].pb(*this);
                        return false;
                }else{
                        for(int i=0;i<vis[key_v].size();i++){
                                if(vis[key_v][i]==*this) return true;
                        }
                        vis[key_v].pb(*this);
                        return false;
                }
	}*/
}st,que[199999];

int ans=0;
void dfs(int step){
        ans=max(st.same_face(),ans);
        if(step==N){
                return ;
        }
	MOFANG tmp=st;
	st.left_up();
	dfs(step+1);

	st=tmp;
	st.left_down();
	dfs(step+1);

	st=tmp;
	st.down_right();
	dfs(step+1);

	st=tmp;
	st.down_left();
	dfs(step+1);

	st=tmp;
	st.front_right();
	dfs(step+1);

	st=tmp;
	st.front_left();
	dfs(step+1);
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif
	while(scanf("%d",&N)!=EOF){
		ans=0;
                memset(vis,0,sizeof(vis));
		//for(int i=0;i<MOD;i++) vis[i].clear();
		for(int i=0;i<24;i++)
			scanf("%d",&st.m[i]);
		dfs(0);
		printf("%d\n",ans);
	}
}


还有不明白为什么这个版本会错,这个没用vis查重复

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <climits>
using namespace std;
#define pb push_back
int N;
const int MOD=999997;
struct MOFANG{
	int m[24];
	int step;
	MOFANG(){memset(m,0,sizeof(m));step=0;}
	bool operator==(MOFANG s){
		bool all_same=true;
		for(int i=0;i<24 && all_same;i++){
			if(m[i]!=s.m[i]) all_same=false;
		}
		return all_same;
	}
	int key(){
		int sum=0;
		for(int i=0;i<24;i++){
			sum=(sum*6+m[i])%MOD;
		}
		return sum%MOD;
	}
	int same_face(){
		int sum=0;
		if(m[6]==m[7] && m[7]==m[13] && m[13]==m[12]) sum++;
		if(m[0]==m[1] && m[1]==m[3] && m[3]==m[2]) sum++;
		if(m[8]==m[9] && m[9]==m[15] && m[15]==m[14]) sum++;
		if(m[16]==m[17] && m[17]==m[19] && m[19]==m[18]) sum++;
		if(m[20]==m[21] && m[21]==m[23] && m[23]==m[22]) sum++;
		if(m[4]==m[5] && m[5]==m[11] && m[11]==m[10]) sum++;
		return sum;
	}
	void left_up(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[20];
		tmp[2]=m[22];
		tmp[6]=m[0];
		tmp[12]=m[2];
		tmp[16]=m[6];
		tmp[18]=m[12];
		tmp[20]=m[16];
		tmp[22]=m[18];
		tmp[4]=m[10];
		tmp[5]=m[4];
		tmp[10]=m[11];
		tmp[11]=m[5];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void left_down(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[0]=m[6];
		tmp[2]=m[12];
		tmp[6]=m[16];
		tmp[12]=m[18];
		tmp[16]=m[20];
		tmp[18]=m[22];
		tmp[20]=m[0];
		tmp[22]=m[2];
		tmp[4]=m[5];
		tmp[5]=m[11];
		tmp[10]=m[4];
		tmp[11]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_right(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[8];
		tmp[3]=m[14];
		tmp[5]=m[3];
		tmp[6]=m[7];
		tmp[7]=m[13];
		tmp[8]=m[17];
		tmp[11]=m[2];
		tmp[12]=m[6];
		tmp[13]=m[12];
		tmp[14]=m[16];
		tmp[16]=m[5];
		tmp[17]=m[11];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void down_left(){
		int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[2]=m[11];
		tmp[3]=m[5];
		tmp[5]=m[16];
		tmp[6]=m[12];
		tmp[7]=m[6];
		tmp[8]=m[2];
		tmp[11]=m[17];
		tmp[12]=m[13];
		tmp[13]=m[7];
		tmp[14]=m[3];
		tmp[16]=m[14];
		tmp[17]=m[8];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_right(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[12];
		tmp[11]=m[13];
		tmp[12]=m[14];
		tmp[13]=m[15];
		tmp[14]=m[21];
		tmp[15]=m[20];
		tmp[16]=m[17];
		tmp[17]=m[19];
		tmp[18]=m[16];
		tmp[19]=m[18];
		tmp[20]=m[11];
		tmp[21]=m[10];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	void front_left(){
                int tmp[24];
		for(int i=0;i<24;i++) tmp[i]=m[i];
		tmp[10]=m[21];
		tmp[11]=m[20];
		tmp[12]=m[10];
		tmp[13]=m[11];
		tmp[14]=m[12];
		tmp[15]=m[13];
		tmp[16]=m[18];
		tmp[17]=m[16];
		tmp[18]=m[19];
		tmp[19]=m[17];
		tmp[20]=m[15];
		tmp[21]=m[14];
		for(int i=0;i<24;i++) m[i]=tmp[i];
	}
	/*bool is_in(){
                int key_v=key();
                if(vis[key_v].size()==0){
                        vis[key_v].pb(*this);
                        return false;
                }else{
                        for(int i=0;i<vis[key_v].size();i++){
                                if(vis[key_v][i]==*this) return true;
                        }
                        vis[key_v].pb(*this);
                        return false;
                }
	}*/
}st,que[MOD/10];

int ans=0;
void bfs(){
	int head=0,tail=0;
	que[tail++]=st;
	while(head<tail){
		MOFANG now=que[head++];
		if(now.step>N) continue;
		ans=max(ans,now.same_face());
		if(now.step==N) continue;
		MOFANG tmp=now;
		tmp.step++;
		tmp.left_up();
		int key=tmp.key();
		que[tail++]=tmp;

		tmp=now;
		tmp.step++;
		tmp.left_down();
		key=tmp.key();
		que[tail++]=tmp;

		tmp=now;
		tmp.step++;
		tmp.down_right();
		key=tmp.key();
		que[tail++]=tmp;

		tmp=now;
		tmp.step++;
		tmp.down_left();
		key=tmp.key();
		que[tail++]=tmp;

		tmp=now;
		tmp.step++;
		tmp.front_right();
		key=tmp.key();
		que[tail++]=tmp;

		tmp=now;
		tmp.step++;
		tmp.front_left();
		key=tmp.key();
                que[tail++]=tmp;
	}
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif
	while(scanf("%d",&N)!=EOF){
		ans=0;
		//for(int i=0;i<MOD;i++) vis[i].clear();
		for(int i=0;i<24;i++)
			scanf("%d",&st.m[i]);
		bfs();
		printf("%d\n",ans);
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值