- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 40149
- 在线时间
- 小时
|
楼主 |
发表于 2010-8-8 11:37:15
|
显示全部楼层
的确,实际上问题1也有上限问题。
关于问题i),现在通过计算机已经能够解决了,只是耗用资源比较大,建议在有2G以上物理内存的计算机上运行:- // cs.cpp : Defines the entry point for the console application.
- //
-
- #include "stdafx.h"
- #include <ctype.h>
- #include <algorithm>
- using namespace std;
- #define NS 47065889
- char st[18];
- char init[9];
- int tc=0;
- long long sl[NS];
- char bs[9][NS];
- long long cc1[NS];
- long long cc2[NS];
- long long *cp1,*cp2;
- #define HASKNIGHT 2
- #define ATTACKED 1
- #define NOTATTACKED 0
-
- //#define DUMP_DATA
- #define ENUM_ALL
- #ifdef ENUM_ALL
-
- void show(int index, bool bothline=false)
- {
- int i;
- for(i=0;i<9;i++){
- switch((sl[index]>>(2*i+18))&3){
- case HASKNIGHT:
- printf("N");
- break;
- case ATTACKED:
- case NOTATTACKED:
- printf("*");
- break;
- }
- }
- printf("\n");
- if(bothline){
- for(i=0;i<9;i++){
- switch((sl[index]>>(2*i))&3){
- case HASKNIGHT:
- printf("N");
- break;
- case ATTACKED:
- case NOTATTACKED:
- printf("*");
- break;
- }
- }
- printf("\n");
- }
- }
-
- void dump(int line, int index)
- {
- int c;
- char st[18];
- show(index);
- c=bs[line][index];
- int i,j,k,bc;
- for(i=0;i<NS;i++){
- if(bs[line-1][i]==0)continue;
- for(j=0;j<18;j++){
- st[j]=(sl[i]>>(2*j))&3;
- }
- for(j=0;j<512;j++){
- bc=0;
- for(k=0;k<9;k++)if((j&(1<<k))!=0)bc++;
- int nc=bs[line-1][i]+bc;
- if(nc!=c)
- continue;
- for(k=0;k<9;k++){
- if(st[k]==NOTATTACKED){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&(j&(1<<(k-1)))!=0)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&(j&(1<<(k+1)))!=0)p=1;
- if(p==0)break;
- }
- }
- if(k<9)continue;
- long long x=0LL;
- for(k=0;k<9;k++){
- int ns=st[k+9];
- if(ns==NOTATTACKED){
- int p=0;
- if(k>=2&&(j&(1<<(k-1)))==0&&(j&(1<<(k-2)))!=0)p=1;
- if(k<7&&(j&(1<<(k+1)))==0&&(j&(1<<(k+2)))!=0)p=1;
- if(p)ns=ATTACKED;
- }
- x|=((long long)ns)<<(2*k);
- }
- for(k=0;k<9;k++){
- int ns;
- if((j&(1<<k))!=0)ns=HASKNIGHT;
- else ns=0;
- if(ns==0){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&st[k-1]==HASKNIGHT)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&st[k+1]==HASKNIGHT)p=1;
- if(k>=2&&(st[k+9-1]!=HASKNIGHT)&&st[k+9-2]==HASKNIGHT)p=1;
- if(k<7&&(st[k+9+1]!=HASKNIGHT)&&st[k+9+2]==HASKNIGHT)p=1;
- if(p==1)ns=1;
- }
- x|=((long long)ns)<<(2*k+18);
- }
- if(x!=sl[index])
- continue;
- if(line>1)
- dump(line-1,i);
- else{
- show(i,true);
- }
- return;
- }
- }
- }
-
- void update_cp(int line)
- {
- int i,j,k,bc;
- for(i=0;i<NS;i++){
- if(bs[line-1][i]==0)continue;
- for(j=0;j<18;j++){
- st[j]=(sl[i]>>(2*j))&3;
- }
- for(j=0;j<512;j++){
- bc=0;
- for(k=0;k<9;k++)if((j&(1<<k))!=0)bc++;
- for(k=0;k<9;k++){
- if(st[k]==NOTATTACKED){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&(j&(1<<(k-1)))!=0)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&(j&(1<<(k+1)))!=0)p=1;
- if(p==0)break;
- }
- }
- if(k<9)continue;
- long long x=0LL;
- for(k=0;k<9;k++){
- int ns=st[k+9];
- if(ns==NOTATTACKED){
- int p=0;
- if(k>=2&&(j&(1<<(k-1)))==0&&(j&(1<<(k-2)))!=0)p=1;
- if(k<7&&(j&(1<<(k+1)))==0&&(j&(1<<(k+2)))!=0)p=1;
- if(p)ns=ATTACKED;
- }
- x|=((long long)ns)<<(2*k);
- }
- for(k=0;k<9;k++){
- int ns;
- if((j&(1<<k))!=0)ns=HASKNIGHT;
- else ns=0;
- if(ns==0){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&st[k-1]==HASKNIGHT)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&st[k+1]==HASKNIGHT)p=1;
- if(k>=2&&(st[k+9-1]!=HASKNIGHT)&&st[k+9-2]==HASKNIGHT)p=1;
- if(k<7&&(st[k+9+1]!=HASKNIGHT)&&st[k+9+2]==HASKNIGHT)p=1;
- if(p==1)ns=1;
- }
- x|=((long long)ns)<<(2*k+18);
- }
- int nc=bs[line-1][i]+bc;
- if(nc>127)nc=127;
- long long *p=lower_bound(sl,sl+NS,x);
- if(p==NULL||p>=sl+NS)continue;
- int index = p-sl;
- if(bs[line][index]==nc){
- cp2[index]+=cp1[index];
- }
- }
- }
- }
-
- void nextline(int line)
- {
- int i,j,k,bc;
- for(i=0;i<NS;i++){
- if(bs[line-1][i]==0)continue;
- for(j=0;j<18;j++){
- st[j]=(sl[i]>>(2*j))&3;
- }
- for(j=0;j<512;j++){
- bc=0;
- for(k=0;k<9;k++)if((j&(1<<k))!=0)bc++;
- for(k=0;k<9;k++){
- if(st[k]==NOTATTACKED){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&(j&(1<<(k-1)))!=0)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&(j&(1<<(k+1)))!=0)p=1;
- if(p==0)break;
- }
- }
- if(k<9)continue;
- long long x=0LL;
- for(k=0;k<9;k++){
- int ns=st[k+9];
- if(ns==NOTATTACKED){
- int p=0;
- if(k>=2&&(j&(1<<(k-1)))==0&&(j&(1<<(k-2)))!=0)p=1;
- if(k<7&&(j&(1<<(k+1)))==0&&(j&(1<<(k+2)))!=0)p=1;
- if(p)ns=ATTACKED;
- }
- x|=((long long)ns)<<(2*k);
- }
- for(k=0;k<9;k++){
- int ns;
- if((j&(1<<k))!=0)ns=HASKNIGHT;
- else ns=0;
- if(ns==0){
- int p=0;
- if(k>=1&&st[k+9-1]!=HASKNIGHT&&st[k-1]==HASKNIGHT)p=1;
- if(k<8&&st[k+9+1]!=HASKNIGHT&&st[k+1]==HASKNIGHT)p=1;
- if(k>=2&&(st[k+9-1]!=HASKNIGHT)&&st[k+9-2]==HASKNIGHT)p=1;
- if(k<7&&(st[k+9+1]!=HASKNIGHT)&&st[k+9+2]==HASKNIGHT)p=1;
- if(p==1)ns=1;
- }
- x|=((long long)ns)<<(2*k+18);
- }
- int nc=bs[line-1][i]+bc;
- if(nc>127)nc=127;
- long long *p=lower_bound(sl,sl+NS,x);
- if(p==NULL||p>=sl+NS)continue;
- int index = p-sl;
- if(bs[line][index]==0||bs[line][index]>nc){
- bs[line][index]=nc;
- }
- }
- }
- printf("Finished line %d\n",line+1);
- }
-
- #define BEST_COUNT 22
- void countall()
- {
- long long *p;
- cp1=cc1,cp2=cc2;
- int i,j;
- for(i=0;i<NS;i++){
- for(j=0;j<18;j++){
- if(((sl[i]>>(2*j))&3)==0)
- break;
- }
- if(j<18)continue;
- if(bs[8][i]!=BEST_COUNT)continue;
- cp1[i]=1LL;
- }
- for(i=8;i>=1;i--){
- update_cp(i);
- p=cp2;
- cp2=cp1;
- cp1=p;
- long long tsize=0ll;
- for(j=0;j<NS;j++)tsize+=cp2[j];
- printf("Total count %lld in step %d\n",tsize,i);
- memset(cp2,0,sizeof(cp2[0])*NS);
- }
- }
-
- int findbestlast()
- {
- int i,j;
- int bc=0;
- int index;
- for(i=0;i<NS;i++){
- for(j=0;j<18;j++){
- if(((sl[i]>>(2*j))&3)==0)
- break;
- }
- if(j<18)continue;
- if(bs[8][i]==0)continue;
- if(bc==0||bs[8][i]<bc){
- bc=bs[8][i];
- index=i;
- }
- }
- printf("best value %d\n",bc);
- dump(8,index);
- return bc;
- }
-
- void init2()
- {
- int i,j;
- for(i=0;i<tc;i++){
- int c2=0;
- for(j=0;j<18;j++){
- st[j]=(sl[i]>>(2*j))&3;
- if(st[j]==2)c2++;
- }
- for(j=0;j<9;j++){
- if(st[j]==ATTACKED){
- int p=0;
- if(j>=2&&st[9+j-2]==HASKNIGHT&&st[9+j-1]!=HASKNIGHT)
- p=1;
- if(j<7&&st[9+j+2]==HASKNIGHT&&st[9+j+1]!=HASKNIGHT)
- p=1;
- if(p==0)break;
- }
- }
- if(j<9){
- continue;
- }
- for(j=0;j<9;j++){
- if(st[j+9]==ATTACKED){
- int p=0;
- if(j>=2&&st[j-2]==HASKNIGHT&&st[j-1]!=HASKNIGHT)
- p=1;
- if(j<7&&st[j+2]==HASKNIGHT&&st[j+1]!=HASKNIGHT)
- p=1;
- if(p==0)break;
- }
- }
- if(j==9){
- bs[0][i]=c2;
- }
- }
- }
- #endif
- void putst()
- {
- #ifdef ENUM_ALL
- long long x=0;
- int i;
- for(i=0;i<18;i++){
- x|=((long long)st[i])<<(2*i);
- }
- sl[tc++]=x;
- #else
- tc++;
- #endif
- }
-
- int next9f()
- {
- int i;
- for(i=0;i<9;i++){
- if(st[i]==2){
- st[i]=0;
- }else{
- break;
- }
- }
- if(i==9)return 0;
- st[i]++;
- return 1;
- }
-
- int passe()
- {
- int i;
- for(i=0;i<9;i++){
- if(st[i]==NOTATTACKED){
- int p=1;
- if(i>=2&&st[9+i-2]==HASKNIGHT&&st[9+i-1]!=HASKNIGHT)p=0;
- if(i<7&&st[9+i+2]==HASKNIGHT&&st[9+i+1]!=HASKNIGHT)p=0;
- if(p==0)return 0;
- }
- }
- for(i=0;i<9;i++){
- if(st[9+i]==NOTATTACKED){
- int p=1;
- if(i>=2&&st[i-2]==HASKNIGHT&&st[i-1]!=HASKNIGHT)p=0;
- if(i<7&&st[i+2]==HASKNIGHT&&st[i+1]!=HASKNIGHT)p=0;
- if(p==0)return 0;
- }
- }
- return 1;
- }
-
- int next18()
- {
- int i;
- for(i=0;i<9;i++){
- if(st[i+9]==2){
- if(init[i]==NOTATTACKED){
- st[i+9]=0;
- }else{
- st[i+9]=1;
- }
- continue;
- }else if(st[i+9]==1){
- st[i+9]=2;
- return 1;
- }else{
- st[i+9]=1;
- return 1;
- }
- }
- return 0;
- }
-
- int first18()
- {
- int i;
- for(i=0;i<9;i++){
- switch(init[i]){
- case NOTATTACKED:
- st[i+9]=NOTATTACKED;
- break;
- case ATTACKED:
- st[i+9]=ATTACKED;
- break;
- default:
- fprintf(stderr,"invalid\n");
- exit(-1);
- }
- }
- return 1;
- }
-
-
- void ana18()
- {
- int i;
- for(i=0;i<9;i++)init[i]=0;
- for(i=0;i<9;i++){
- if(st[i]==HASKNIGHT){
- if(i>=2&&st[i-1]!=HASKNIGHT){
- init[i-2]=ATTACKED;
- }
- if(i<7&&st[i+1]!=HASKNIGHT)init[i+2]=ATTACKED;
- }
- }
- if(!first18())
- return;
- do{
- if(passe()){
- putst();
- }
- }while(next18());
- }
-
- void checkboard()
- {
- char status[10][9];
- char line[80];
- int i,j;
- for(i=0;i<10;i++){
- gets(line);
- int c=0;
- char *p=line;
- do{
- while(isspace(*p))p++;
- if(*p=='\0'){
- fprintf(stderr,"invalid input\n");
- exit(-1);
- }
- if(*p=='*')
- status[i][c++]=NOTATTACKED;
- else
- status[i][c++]=HASKNIGHT;
- p++;
- }while(c<9);
- }
- long long x;
- int c=0;
- for(i=0;i<9;i++)if(status[0][i]==HASKNIGHT)c++;
- for(i=0;i<9;i++){///line i and line i+1
- x=0ll;
- for(j=0;j<9;j++){
- if(status[i+1][j]==HASKNIGHT){
- if(j>=2&&status[i+1][j-1]!=HASKNIGHT&&status[i][j-2]==NOTATTACKED){
- status[i][j-2]=ATTACKED;
- }
- if(j<7&&status[i+1][j+1]!=HASKNIGHT&&status[i][j+2]==NOTATTACKED){
- status[i][j+2]=ATTACKED;
- }
- }
- if(status[i][j]==HASKNIGHT){
- if(j>=2&&status[i][j-1]!=HASKNIGHT&&status[i+1][j-2]==NOTATTACKED){
- status[i+1][j-2]=ATTACKED;
- }
- if(j<7&&status[i][j+1]!=HASKNIGHT&&status[i+1][j+2]==NOTATTACKED){
- status[i+1][j+2]=ATTACKED;
- }
- }
- if(i>0&&status[i-1][j]==HASKNIGHT){
- if(j>=1&&status[i][j]!=HASKNIGHT&&status[i+1][j-1]==NOTATTACKED){
- status[i+1][j-1]=ATTACKED;
- }
- if(j<8&&status[i][j]!=HASKNIGHT&&status[i+1][j+1]==NOTATTACKED){
- status[i+1][j+1]=ATTACKED;
- }
- }
-
- }
- if(i>0){//check line i-1, everything is attacked
- for(j=0;j<9;j++){
- if(status[i-1][j]==NOTATTACKED){
- int p=0;
- if(j>=1&&status[i+1][j-1]==HASKNIGHT&&status[i][j-1]!=HASKNIGHT){
- p=1;
- }
- if(j<8&&status[i+1][j+1]==HASKNIGHT&&status[i][j+1]!=HASKNIGHT){
- p=1;
- }
- if(p==0){
- fprintf(stderr,"invalid input, location %d,%d not attacked\n",i-1,j);
- exit(-1);
- }
- }
- }
- }
- for(j=0;j<9;j++){
- if(status[i+1][j]==HASKNIGHT)c++;
- x|=((long long)status[i][j])<<(2*j);
- x|=((long long)status[i+1][j])<<(2*j+18);
- }
- long long *p=lower_bound(sl,sl+NS,x);
- if(p==NULL||p>=sl+NS){
- fprintf(stderr,"status %llx in line %d~%d not found\n",x,i,i+1);
- exit(-1);
- }
- int index=p-sl;
- if(bs[i][index]==0||bs[i][index]>c){
- fprintf(stderr,"status %llx(index %d) in line %d~%d only use %d knights while limit is %d\n",x,index,i,i+1,c,bs[i][index]);
- nextline(i);
- exit(-1);
- }
- printf("status %llx(index %d) in line %d~%d use %d knights and limit is %d\n",x,index,i,i+1,c,bs[i][index]);
- }
- printf("success\n");
- }
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- int i;
- #if 0
- do{
- ana18();
- }while(next9f());
- printf("total %d states\n",tc);
- if(tc!=NS){
- fprintf(stderr,"invalid count\n");
- return -1;
- }
- sort(sl,sl+NS);
- FILE *f=fopen("stats.dat","wb");
- fwrite(sl,sizeof(sl[0]),NS,f);
- fclose(f);
- tc=NS;
- #else
- FILE *f=fopen("stats.dat","rb");
- fread(sl,sizeof(sl[0]),NS,f);
- fclose(f);
- tc=NS;
- #endif
- #ifdef ENUM_ALL
- #ifdef DUMP_DATA
- init2();
- for(i=0;i<8;i++){
- nextline(i+1);
- }
- FILE *q=fopen("data.dat","wb");
- fwrite(bs,sizeof(bs[0][0]),9*NS,q);
- #else
- FILE *q=fopen("data.dat","rb");
- fread(bs,sizeof(bs[0][0]),9*NS,q);
- #endif
- fclose(q);
- // checkboard();
- findbestlast();
- // countall();
- #endif
- return 0;
- }
-
复制代码 |
|