恋_紫花地丁吧 关注:20贴子:374
  • 11回复贴,共1

关于猜图游戏的一些有趣的事

只看楼主收藏回复

记得JSOI这题中有说到保证构造的图为唯一,密码吧也N多次用到过,最后总能解出唯一一张图,于是很长时间我都认为任意一种合法的序列都有唯一的图与之对应,直到我打算为此写一段程序以减少冗杂的苦力并认真思考这个问题时,才发现很容易构造出一种序列使解不唯一,例如下图,两种图都为合法方案,当方格数为3*3,4*4都能构造出相应的"碰撞",可见"碰撞"的存在并非特例



1楼2012-10-19 22:16回复
    于是我的兴趣从仅仅写出这个游戏的程序,转到研究满足怎样条件的序列拥有碰撞,并且序列最多有多少种不同满足条件的解上了


    2楼2012-10-19 22:21
    回复
      2025-05-30 07:29:49
      广告
      #include<iostream>
      #include<fstream>
      using namespace std;
      ifstream fin("guess.in");ofstream fout("guess.out");
      int len=0,a[100]={0},sss[100]={0},m,n;
      long white_answer=0,black_answer=0;//black_answer 中0为黑子 , white_answer 中1为白子
      long white_sure=0,black_sure=0;// black_sure 中1为黑子 , white_sure 中0为白子
      long fill(long ss,int j,int l){long temp=0;for (int i=1;i<=l;i++){temp=temp*2+1;}temp=temp<<len-j+1-l;return ss|temp;}
      char map[100][100]={'u'};
      int state[2][100][100]={0};
      void dfs(long s,int j,int k)
      {
      if (((s>>(len-j))&(black_sure>>(len-j)))!=(black_sure>>(len-j)))return;
      if (((s>>(len-j))|(white_sure>>(len-j)))!=(white_sure>>(len-j)))return;
      if (k>a[0]){black_answer=s|black_answer;white_answer=white_answer&s;return;}
      for (int i=j;i<=len-sss[k]+1;i++)dfs(fill(s,i,a[k]),i+1+a[k],k+1);
      }
      void search(int flag,int line)
      {
      if (flag==0)len=n; else len=m;
      for(int i=1;i<=state[flag][line][0];i++)a[i]=state[flag][line][i];
      white_answer=0;black_answer=0;
      for(int i=1;i<=len;i++)white_answer=white_answer*2+1;
      dfs(0,1,1);
      }
      void init(){sss[a[0]+1]=-1;for (int i=a[0];i>=1;i--){sss[i]=sss[i+1]+a[i]+1;}}
      main()
      {
      fin>>m>>n;
      for (int i=1;i<=n;i++)
      {
      fin>>state[1][i][0];for(int j=1;j<=state[1][i][0];j++)fin>>state[1][i][j];
      }
      black_sure=0;
      fin>>len>>a[0];
      white_sure=white_answer;
      init();
      fout<<white_answer<<endl<<black_answer;
      return 0;
      }
      保存下进度,虽然不知道下次继续这个进度是在什么时候了 TAT~~


      IP属地:江苏5楼2012-11-11 16:42
      收起回复
        #include<iostream>
        #include<fstream>
        using namespace std;
        ifstream fin("guess.in");ofstream fout("guess.out");
        int len=5,a[100]={2,3,1},sss[100]={0},m,n,nnn=0,mmm=0,front=1,rail=1,queue[2][90000]={0},sum,now=0;
        long white_answer=0,black_answer=0;//black_answer 中0为黑子 , white_answer 中1为白子
        long white_sure=0,black_sure=0;// black_sure 中1为黑子 , white_sure 中0为白子
        char map[100][100]={'u'};
        void init(){sss[a[0]+1]=-1;for (int i=a[0];i>=1;i--){sss[i]=sss[i+1]+a[i]+1;}}
        long fill(long ss,int j,int l)
        {long temp=0;
        for (int i=1;i<=l;i++)
        {temp=temp*2+1;}
        temp=temp<<(len-j+1-l);
        return ss|temp;
        } int state[2][100][100]={0};
        void dfs(long s,int j,int k)
        {
        int temp=len-j;
        if (temp<0)temp=0;
        if (((s>>(temp))&(black_sure>>(temp)))!=(black_sure>>(temp)))return;
        if (((s>>(temp))|(white_sure>>(temp)))!=(white_sure>>(temp)))return;
        if (k>a[0]){black_answer=s|black_answer;white_answer=white_answer&s;return;}
        for (int i=j;i<=len-sss[k]+1;i++)
        dfs(fill(s,i,a[k]),i+1+a[k],k+1);
        }
        void search(int flag,int line)
        {
        white_sure=0,black_sure=0;white_answer=0;
        if (flag==0)
        {
        len=m;white_answer=mmm;
        for(int i=1;i<=m;i++)
        {
        if (map[i][line]=='b')black_sure=(black_sure*2)+1;else black_sure=black_sure*2;
        if (map[i][line]=='w')white_sure=white_sure*2;else white_sure=white_sure*2+1;
        }
        }
        else
        {
        len=n;white_answer=nnn;
        for(int i=1;i<=n;i++)
        {
        if (map[line][i]=='b')black_sure=(black_sure>>1)+1;else black_sure=black_sure>>2;
        if (map[line][i]=='w')white_sure=white_sure>>1;else white_sure=white_sure*2+1;
        }
        }
        memset(a,0,sizeof(a));
        a[0]=state[flag][line][0];
        for(int i=1;i<=state[flag][line][0];i++)a[i]=state[flag][line][i];
        black_answer=0;
        init();
        dfs(0,1,1);
        if (flag==0)
        {
        for (i=m;i>=1;i--)
        {
        if (((black_answer & 1)==0)&&(map[i][line]!='w')){map[i][line]='w';queue[0][rail]=1;queue[1][rail]=line;rail++;}
        if (((white_answer & 1)==1)&&(map[i][line]!='b')){map[i][line]='b';queue[0][rail]=1;queue[1][rail]=line;rail++;now++;}
        black_answer=black_answer>>1;
        white_answer=white_answer>>1;
        }
        }
        else
        {
        for (i=n;i>=1;i--)
        {
        if (((black_answer & 1)==0)&&(map[line][i]!='w')){map[line][i]='w';queue[0][rail]=0;queue[1][rail]=line;rail++;}
        if (((white_answer & 1)==1)&&(map[line][i]!='b')){map[line][i]='b';queue[0][rail]=0;queue[1][rail]=line;rail++;now++;}
        black_answer=black_answer>>1;white_answer=white_answer>>1;
        }
        }
        } main()
        {
        fin>>m>>n;
        for (int i=1;i<=n;i++)nnn=nnn*2+1;
        for ( i=1;i<=m;i++)mmm=mmm*2+1;
        for ( i=1;i<=m;i++)
        {
        fin>>state[1][i][0];
        for(int j=1;j<=state[1][i][0];j++)fin>>state[1][i][j];
        }
        for (i=1;i<=n;i++)
        {
        fin>>state[0][i][0];
        for(int j=1;j<=state[0][i][0];j++)fin>>state[0][i][j];
        }
        fin>>sum;
        for(i=1;i<=m;i++){queue[0][rail]=1;queue[1][rail]=i;rail++;}//入队
        for(i=1;i<=n;i++){queue[0][rail]=0;queue[1][rail]=i;rail++;}
        while ((front!=rail)&&(now<=sum))
        {
        search(queue[0][front],queue[1][front]);
        front++;//出队 }
        for (i=1;i<=n;i++)
        {
        for (int j=1;j<=m;j++)
        {
        fout<<map[j][i];
        }
        fout<<endl;
        }
        return 0;
        }
        算法部分完成,窗体部分代码完成,接下来只有细微的一些调整了


        IP属地:江苏6楼2012-11-17 21:16
        收起回复
          #include<iostream>
          #include<fstream>
          using namespace std;
          ifstream fin("guess.in");ofstream fout("guess.out");
          int len=5,a[100]={2,3,1},sss[100]={0},m,n,nnn=0,mmm=0,front=1,rail=1,queue[2][1000]={0},sum,now=0,stop;
          long white_answer=0,black_answer=0;//black_answer 中0为黑子 , white_answer 中1为白子
          long white_sure=0,black_sure=0;// black_sure 中1为黑子 , white_sure 中0为白子
          char map[100][100]={'u'};
          void init(){sss[a[0]+1]=-1;for (int i=a[0];i>=1;i--){sss[i]=sss[i+1]+a[i]+1;}}
          long fill(long ss,int j,int l)
          {long temp=0;
          for (int i=1;i<=l;i++)
          {temp=temp*2+1;}
          temp=temp<<(len-j+1-l);
          return ss|temp;
          }
          int state[2][100][100]={0};
          void dfs(long s,int j,int k)
          {
          int temp=len-j+1;
          if (temp<0)temp=0;
          if (((s>>(temp))&(black_sure>>(temp)))!=(black_sure>>(temp)))return;
          if (((s>>(temp))|(white_sure>>(temp)))!=(white_sure>>(temp)))return;
          if (k>a[0]){black_answer=s|black_answer;white_answer=white_answer&s;return;}
          for (int i=j;i<=len-sss[k]+1;i++)
          dfs(fill(s,i,a[k]),i+1+a[k],k+1);
          }
          void search(int flag,int line)
          {
          white_sure=0,black_sure=0;white_answer=0;
          if (flag==0)
          {
          len=m;white_answer=mmm;
          for(int i=1;i<=m;i++)
          {
          if (map[i][line]=='b')black_sure=(black_sure*2)+1;else black_sure=black_sure*2;
          if (map[i][line]=='w')white_sure=white_sure*2;else white_sure=white_sure*2+1;
          }
          }
          else
          {
          len=n;white_answer=nnn;
          for(int i=1;i<=n;i++)
          {
          if (map[line][i]=='b')black_sure=(black_sure*2)+1;else black_sure=black_sure*2;
          if (map[line][i]=='w')white_sure=white_sure*2;else white_sure=white_sure*2+1;
          }
          }
          memset(a,0,sizeof(a)); a[0]=state[flag][line][0];
          for(int i=1;i<=state[flag][line][0];i++)a[i]=state[flag][line][i];
          black_answer=0;init();dfs(0,1,1);
          if (flag==0)
          {
          for (i=m;i>=1;i--)
          {
          if (((black_answer & 1)==0)&&(map[i][line]==0)){map[i][line]='w';queue[0][rail]=1;queue[1][rail]=i;rail++;}
          if (((white_answer & 1)==1)&&(map[i][line]==0)){map[i][line]='b';queue[0][rail]=1;queue[1][rail]=i;rail++;now++;}
          black_answer=black_answer>>1;
          white_answer=white_answer>>1;
          }
          }
          else
          {
          for (i=n;i>=1;i--)
          {
          if (((black_answer & 1)==0)&&(map[line][i]==0)){map[line][i]='w';queue[0][rail]=0;queue[1][rail]=i;rail++;}
          if (((white_answer & 1)==1)&&(map[line][i]==0)){map[line][i]='b';queue[0][rail]=0;queue[1][rail]=i;rail++;now++;}
          black_answer=black_answer>>1;white_answer=white_answer>>1;
          }
          }
          }
          main()
          {
          fin>>m>>n;
          for (int i=1;i<=n;i++)nnn=nnn*2+1;
          for ( i=1;i<=m;i++)mmm=mmm*2+1;
          for ( i=1;i<=m;i++)
          {
          fin>>state[1][i][0];
          for(int j=1;j<=state[1][i][0];j++)fin>>state[1][i][j];
          }
          for (i=1;i<=n;i++)
          {
          fin>>state[0][i][0];
          for(int j=1;j<=state[0][i][0];j++)fin>>state[0][i][j];
          }
          fin>>sum;
          for(i=1;i<=m;i++){queue[0][rail]=1;queue[1][rail]=i;rail++;}//入队
          for(i=1;i<=n;i++){queue[0][rail]=0;queue[1][rail]=i;rail++;}
          while ((front!=rail)&&(now<=sum))
          {
          search(queue[0][front],queue[1][front]);
          front++;//出队
          }
          for (i=1;i<=n;i++)
          {
          for (int j=1;j<=m;j++)
          {
          if(map[j][i]==0) fout<<' ';
          else fout<<map[j][i];
          }
          fout<<endl;
          }
          return 0;
          }
          完美去bug版


          IP属地:江苏7楼2012-11-23 20:37
          回复