|
发表于 2023-9-25 22:31:09
|
显示全部楼层
更新一个代码,可以将7x7的所有解输出来,比如:
代码编译时通过编译选项-DDALL可以将所有解输出- #include <stdio.h>#include <time.h>#include <map>#include <vector>#define N 7#define EMPT 0#define B1 1#define B2H 2#define B2L 3#define B3H 4#define B3L 5#define B4H 6#define B4L 7std::map<long,long> s2c[N*N];#ifdef DALLstd::map<long, long> prev[N*N];#endifstatic char bsbits[4]={7,3,3,1};static char bsstart[4]={0,3,5,7};struct DS{ char uc[4]; char bs[N+1];};int getuc(long v, int bs){ int r=(v>>55)&255; return (r>>bsstart[bs])&bsbits[bs];}long setuc(long v,int bs, int s){ int off=55+bsstart[bs]; v&=~(((1L<<bsbits[bs])-1)<<off); v|=((long)s)<<off; return v;}int getposstat(long v, int k){ return (v>>(k*5))&31;}long setposstat(long v, int k, int s){ int off=k*5; v&=~(31L<<off); v|=(long)s<<off; return v;}int getstattype(int s){ return (s>>2)&7;}int getstatoff(int s){ return s&3;}int createstat(int type, int off){ return (type<<2)|off;}void decode(long v, DS& ds){ int i; for(i=0;i<4;i++)ds.uc[i]=getuc(v,i); for(i=0;i<N+1;i++)ds.bs[i]=getposstat(v,i);}long encode(const DS& ds){ long v=0L; int i; for(i=0;i<4;i++)v=setuc(v,i,ds.uc[i]); for(i=0;i<N+1;i++)v=setposstat(v,i,ds.bs[i]); return v;}#define CS(t,o) createstat(t,o)void outds(const DS& ds, int ne=0){ int i; if(ne==0){ printf("UC{"); for(i=0;i<4;i++){printf(" %d", ds.uc[i]);} printf(" } "); } for(i=0;i<N+1;i++){ if(ne&&i==N)break; if(ds.bs[i]==CS(EMPT,0))printf("E "); else printf("%c%d%d",getstattype(ds.bs[i])&1?'|':'-',getstattype(ds.bs[i])/2+1,getstatoff(ds.bs[i])); } printf("\n");}void init0(){ long x=0;//all empty int i,j; DS ds; for(i=0;i<8;i++){//all 8 stattype ds.uc[0]=ds.uc[1]=ds.uc[2]=ds.uc[3]=0; for(j=0;j<N+1;j++)ds.bs[j]=0; int s = CS(i,0); //The first block in stat s x = 0; ds.bs[0]=s; if(i!=EMPT){ int uc=i>>1; ds.uc[i>>1]=1; } s2c[0].insert(std::make_pair(encode(ds),1)); }}#ifdef DEBUG#define DUMP(a,b,c) dump(a,b,c)#else#define DUMP(a,b,c)#endifvoid dump(int id, const DS& dsf, const DS& dst){ printf("(%d,%d)\n",id/N,id%N); printf("FROM ");outds(dsf); printf("TO ");outds(dst); printf("\n");}#ifdef DALL#define IM1 (i-1)#define NM1 (N*N-1)#define I (i)std::vector<long> status_stack;void outputresult(){ int i; for(i=status_stack.size()-1;i>=0;i--){ DS ds1; decode(status_stack[i],ds1); outds(ds1,1); } printf("\n");}void trace(long status, int level){ int i,j; if(level%N==N-1){ status_stack.push_back(status); if(level==N-1){ outputresult(); status_stack.pop_back(); return; } } if(level==0)return; std::map<long, long>::iterator mit; DS ds1, ds2; { decode(status, ds1); mit = prev[level].find(status); for(i=0;i<64;i++){ if(mit->second&(1L<<i)){ int vN=i/8; int vi=i%8; ds2=ds1; if(vi<=1){ ds2.bs[level%N]=CS(vi,0); }else if(vi&1){//lie if(getstattype(ds1.bs[level%N])==vi){ ds2.bs[level%N]=CS(vi, getstatoff(ds1.bs[level%N])-1); }else{ ds2.bs[level%N]=CS(vi, vi/2); } }else{//hang if(level%N==N-1||getstattype(ds1.bs[(level+1)%N])!=vi){ ds2.bs[level%N]=CS(vi, vi/2); }else{ ds2.bs[level%N]=CS(vi, getstatoff(ds1.bs[(level+1)%N])-1); } } if(level%N==0){ ds2.bs[N]=0; }else if(vN<=1){ ds2.bs[N]=CS(vN,0); }else if(vN&1){//lie if(getstattype(ds1.bs[(level-1)%N])==vN){ ds2.bs[N]=CS(vN, getstatoff(ds1.bs[(level-1)%N])-1); }else{ ds2.bs[N]=CS(vN, vN/2); } }else{//hang if(getstattype(ds2.bs[level%N])==vN){ ds2.bs[N]=CS(vN, getstatoff(ds2.bs[level%N])-1); }else{ ds2.bs[N]=CS(vN, vN/2); } } if(getstattype(ds1.bs[level%N])>0 && getstatoff(ds1.bs[level%N])==0){ ds2.uc[getstattype(ds1.bs[level%N])/2]--; } long v=encode(ds2); std::map<long, long>::iterator mit2; mit2 = s2c[level-1].find(v); if(mit2 != s2c[level-1].end()){ trace(mit2->first, level-1); }else{ printf("Invalid reverse finding:\n"); DUMP(level-1,ds2,ds1); } } } } if(level%N==N-1){ status_stack.pop_back(); }}#else#define IM1 ((i-1)%2)#define NM1 ((N-1)%2)#define I ((i)%2)#endifint main(){ int i; DS ds1,ds2; time_t t=time(NULL); init0(); std::map<long,long>::iterator mit; for(i=1;i<=N*N-1;i++){#ifndef DALL s2c[i%2].clear();#endif for(mit=s2c[IM1].begin();mit!=s2c[IM1].end();++mit){ decode(mit->first,ds1);// printf("from ");outds(ds1); int nexttype=-1; if(i>=N){ int os=ds1.bs[i%N]; int st =getstattype(os); int sp = getstatoff(os); if(st>=B1)nexttype=CS(EMPT,0); if(st>=B2H&&(st&1)){//lie if(sp<(st/2)){ nexttype=CS(st,sp+1); } } } if(i%N>0){ int os=ds1.bs[i%N-1]; int st = getstattype(os); int sp = getstatoff(os); if(getstattype(ds1.bs[N])!=EMPT){ if(nexttype!=-1&&nexttype!=CS(EMPT,0))continue; nexttype=CS(EMPT,0); } if(i%N<N-1&&getstattype(ds1.bs[i%N+1])!=EMPT){ if(nexttype!=-1&&nexttype!=CS(EMPT,0))continue; nexttype=CS(EMPT,0); } if(st>=B1){ if(nexttype!=-1&&nexttype!=CS(EMPT,0))continue; if(st>=B2H&&!(st&1)){//hang if(sp<(st/2)){ if(nexttype>=0)continue; nexttype=CS(st,sp+1); } } if(nexttype<0)nexttype=CS(EMPT,0); } } if(nexttype>=0){ ds2=ds1; ds2.bs[i%N]=nexttype; int pvs = 0; pvs=getstattype(ds1.bs[N])*8+getstattype(ds1.bs[i%N]); if(i%N==N-1){ ds2.bs[N]=CS(EMPT,0); }else{ ds2.bs[N]=ds1.bs[i%N]; } long v = encode(ds2); s2c[I][v]+=mit->second;#ifdef DALL prev[I][v]|=1L<<pvs;#endif DUMP(i,ds1,ds2); }else{ int j; int pvs = getstattype(ds1.bs[N])*8+getstattype(ds1.bs[i%N]); for(j=0;j<8;j++){//try put stattype j int s = CS(j,0); //The block i in stat s ds2=ds1; if(j>=B2H){ if(j&1){ if(i/N+(j/2)+1>N)continue; }else{ if(i%N+(j/2)+1>N)continue; } } ds2.bs[i%N]=s; if(i%N==N-1){ ds2.bs[N]=CS(EMPT,0); }else{ ds2.bs[N]=ds1.bs[i%N]; } if(j>0){ int cc=j/2; if(ds2.uc[cc]+cc>=4)continue; ds2.uc[cc]++; } long v=encode(ds2); s2c[I][v]+=mit->second;#ifdef DALL prev[I][v]|=1L<<pvs;#endif DUMP(i,ds1,ds2); } } } long time_diff = time(NULL)-t; printf("Total %ld stats for level %d (%ld s)\n",s2c[I].size(),i,time_diff); fflush(stdout); } long total=0; for(mit=s2c[NM1].begin();mit!=s2c[NM1].end();++mit){#ifndef DALL printf("status %lx count %ld\n",mit->first, mit->second);#endif decode(mit->first,ds1);#ifndef DALL outds(ds1);#endif for(i=0;i<4;i++){ if(ds1.uc[i]+i!=4)break; } if(i<4)continue; for(i=0;i<N;i++){ if(getstattype(ds1.bs[i])&1){//lie if(getstattype(ds1.bs[i])/2!=getstatoff(ds1.bs[i]))break; } } if(i<N)continue;#ifdef DALL trace(mit->first, NM1);#endif total+=mit->second; } printf("Total %ld\n",total);}
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|