UVA - 1533 - Moving Pegs

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA - 1533 - Moving Pegs相关的知识,希望对你有一定的参考价值。

题目链接:UVA-1533

题目大意:

有一个棋盘如下,黑色表示有棋子,白色表示空,棋盘初始状态为有一个位置n为空,其他位置都有棋子。

技术分享

每次可以选择一个棋子在一条直线上隔一个或连续多个棋子跳到空白位置,然后这一个或多个棋子就被拿走,问最少几步可以使棋盘上的棋子拿走到只剩下一个且位置和初始空白位置相同。输出几步和每步的起始与落子位置。输出字典序最小的解,无解输出IMPOSSIBLE。

题目分析:

可以直接BFS计算。

但是状态太多,需要进行状态压缩。

将当前状态用二进制保存。

每个点最多可以有六种移动方向,用数组表示出每个点的移动方向。

关键是二进制运算符的用法,如下:

1.& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
2.| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
3.^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
4.~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
5.<< 左移 用来将一个数的各二进制位全部左移N位,右补0
6.>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0

给出代码:

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <string>
  6 #include <queue>
  7 #include <algorithm>
  8 using namespace std;
  9 const int N=15;
 10 int mp[1 << N];
 11 int flag[15][6] = {{-1,-1,-1,-1,2,3},{-1,1,-1,3,4,5},{1,-1,2,-1,5,6},
 12     {-1,2,-1,5,7,8},{2,3,4,6,8,9},{3,-1,5,-1,9,10},
 13     {-1,4,-1,8,11,12},{4,5,7,9,12,13},{5,6,8,10,13,14},
 14     {6,-1,9,-1,14,15},{-1,7,-1,12,-1,-1},{7,8,11,13,-1,-1},
 15     {8,9,12,14,-1,-1},{9,10,13,15,-1,-1},{10,-1,14,-1,-1,-1}
 16 };
 17 int n;
 18 struct P
 19 {
 20     int S;
 21     int num;
 22     int mark[16][3];
 23     int step;
 24 };
 25 int bfs(int s)
 26 {
 27     queue<P> p;
 28     while(!p.empty())
 29         p.pop();
 30     P a;
 31     a.S=s;
 32     a.step=0;
 33     a.num=1;
 34     p.push(a);
 35     while(!p.empty())
 36     {
 37         //cout<<"*"<<endl;
 38         P u=p.front();
 39         p.pop();
 40         //  cout<<u.S<<endl;
 41         for(int i=0; i<15; i++)
 42         {
 43             if(u.S&(1<<i))
 44             {
 45                 for(int j=0; j<6; j++)
 46                 {
 47                     P b=u;
 48                     int cur=i;
 49                     if(flag[i][j]!=-1&&b.S&(1<<(flag[i][j]-1)))
 50                     {
 51                         while(cur!=-1&&b.S&(1<<cur))
 52                         {
 53                             b.S^=(1<<cur);
 54                             cur=flag[cur][j]-1;
 55                             b.num++;
 56                         }
 57                         if(cur<0)
 58                             continue;
 59                         b.S|=(1<<cur);
 60                         b.step=u.step+1;
 61                         b.mark[b.step][0]=i;
 62                         b.mark[b.step][1]=cur;
 63                         b.num--;
 64                         if(!mp[b.S])
 65                         {
 66                             if(b.num==14&&b.S&(1<<(n-1)))
 67                             {
 68                                 printf("%d\n%d %d", b.step, b.mark[1][0] + 1, b.mark[1][1] + 1);
 69                                 for (int k = 2; k <= b.step; k++)
 70                                     printf(" %d %d", b.mark[k][0] + 1, b.mark[k][1] + 1);
 71                                 printf("\n");
 72                                 return 1;
 73                             }
 74                             mp[b.S]=1;
 75                             p.push(b);
 76                         }
 77 
 78                     }
 79                 }
 80             }
 81         }
 82     }
 83     return 0;
 84 }
 85 int main()
 86 {
 87     int T;
 88     cin>>T;
 89     while(T--)
 90     {
 91         cin>>n;
 92         memset(mp,0,sizeof(mp));
 93         int temp = ((1 << 15) - 1) ^ (1 << (n - 1));
 94         mp[temp]=1;
 95         int res = bfs(temp);
 96         if (!res)
 97             printf("IMPOSSIBLE\n");
 98     }
 99     return 0;
100 }
View Code

 

以上是关于UVA - 1533 - Moving Pegs的主要内容,如果未能解决你的问题,请参考以下文章

UVA 356 - Square Pegs And Round Holes

uva live 2326 - Moving Tables

UVa 10201 Adventures in Moving - Part IV

10_InfluxDB常用函数变换类函数(DERIVATIVE, DIFFERENCE,ELAPSED,MOVING_AVERAGE,NON_NEGATIVE_DERIVATIVE)等(代

c_cpp Pegs - Copy.cpp

[CodeForces] Moving Points