题意:
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);
}
}