- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 40149
- 在线时间
- 小时
|
发表于 2022-8-27 11:10:24
|
显示全部楼层
更新一个代码,可以将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 7
- std::map<long,long> s2c[N*N];
- #ifdef DALL
- std::map<long, long> prev[N*N];
- #endif
- static 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)
- #endif
- void 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)
- #endif
- int 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);
- }
复制代码 |
|