UVA-1533 Moving Pegs (BFS+位压缩)

Description

Venture MFG Company, Inc. has made a game board. This game board has 15 holes and these holes are filled with pegs except one hole. A peg can jump over one or more consecutive peg s to the nearest empty hole along the straight line. As a peg jump over the pegs you remove them from the board. In the following figure, the peg at the hole number 12 or the peg at the hole number 14 can jump to the empty hole number 5. If the peg at the hole number 12 is moved then the peg at the hole number 8 is removed. Instead, if the peg at the hole number 14 is moved then the peg at the hole number 9 is removed.

                    

Write a program which find a shortest sequence of moving pegs to leave the last peg in the hole that was initially empty. If such a sequence does not exist the program should write a message ``IMPOSSIBLE".

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case is a single integer which means an empty hole number.

Output

For each test case, the first line of the output file contains an integer which is the number of jumps in a shortest sequence of moving pegs. In the second line of the output file, print a sequence of peg movements. A peg movement consists of a pair o f integers separated by a space. The first integer of the pair denotes the hole number of the peg that is moving, and the second integer denotes a destination (empty) hole number.

If there are multiple solutions, output the lexicographically smallest one.

Sample Input

1
5

Sample Output

10
12 5 3 8 15 12 6 13 7 9 1 7 10 8 7 9 11 14 14 5

题目大意:在如图中的棋盘(固定5行)上,每个棋子的走法类似于象棋中“炮”的走法,只能隔着棋子沿直线走,每走一步造成的效果是该棋子落到第一个空白处,并且沿途经过的棋子全部消失。求使最后一个棋子恰好落在第n个点上的最短、字典序最小的路径。题目分析:这道题说白了有15个位置,每个位置上可能有棋子也可能没有棋子,棋子的状况总共有2^15种。起点是(2^15)-1,终点是1<<(n-1),BFS即可,状态转移也不难,但比较复杂。

代码如下:
# include<iostream>
# include<cstdio>
# include<queue>
# include<map>
# include<cmath>
# include<string>
# include<cstring>
# include<algorithm>

using namespace std;

const int tot=(1<<15)-1;

struct node
{
    int s,t;
    string step;
    node(int _s,int _t,string _step):s(_s),t(_t),step(_step){}
    bool operator < (const node &a) const {
        if(t==a.t)
            return step>a.step;
        return t>a.t;
    }
};

int mark[1<<15];
map<int,char>mp;
int d[6][2]={{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}};

int get_pos(int x,int y)
{
    return x*(x-1)/2+y;
}

void get_XY(int n,int &x,int &y)
{
    x=1;
    for(int i=1;i<=5&&n-i>0;++i)
        ++x,n-=i;
    y=n;
}

bool ok(int x,int y)
{
    if(x>=1&&x<=5&&y>=1&&y<=x)
        return true;
    return false;
}

void print(string p)
{
    for(int i=0;i<p.size();++i)
        printf("%d%c",p[i]-‘A‘+1,(i==p.size()-1)?‘\n‘:‘ ‘);
}

void bfs(int goal)
{
    priority_queue<node>q;
    memset(mark,0,sizeof(mark));
    mark[tot^goal]=1;
    q.push(node(tot^goal,0,""));
    while(!q.empty())
    {
        node u=q.top();
        q.pop();
        //cout<<u.t<<‘ ‘<<u.s<<‘ ‘<<u.step<<endl;
        if(u.s==goal){
            printf("%d\n",u.t);
            print(u.step);
            return ;
        }
        int x,y;
        for(int i=1;i<=15;++i){
            if(u.s&(1<<(i-1))){
                get_XY(i,x,y);
                for(int j=0;j<6;++j){
                    int nx=x+d[j][0],ny=y+d[j][1];
                    if(!ok(nx,ny))
                        continue;
                    int pos=get_pos(nx,ny);
                    if(!(u.s&(1<<(pos-1))))
                        continue;
                    int s=u.s^(1<<(i-1));
                    while(u.s&(1<<(pos-1)))
                    {
                        s^=(1<<(pos-1));
                        nx=nx+d[j][0],ny=ny+d[j][1];
                        if(!ok(nx,ny))
                            break;
                        pos=get_pos(nx,ny);
                    }
                    s^=(1<<(pos-1));
                    string step=u.step+mp[i];
                    step+=mp[get_pos(nx,ny)];
                    if(ok(nx,ny)&&!mark[s]){
                        mark[s]=1;
                        q.push(node(s,u.t+1,step));
                    }
                }
            }
        }
    }
    printf("IMPOSSIBLE\n");
}

int main()
{
    for(int i=1;i<=15;++i)
        mp[i]=i+‘A‘-1;
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        bfs(1<<(n-1));
    }
    return 0;
}

  

时间: 2024-08-24 11:55:18

UVA-1533 Moving Pegs (BFS+位压缩)的相关文章

UVA - 1533 - Moving Pegs

题目链接:UVA-1533 题目大意: 有一个棋盘如下,黑色表示有棋子,白色表示空,棋盘初始状态为有一个位置n为空,其他位置都有棋子. 每次可以选择一个棋子在一条直线上隔一个或连续多个棋子跳到空白位置,然后这一个或多个棋子就被拿走,问最少几步可以使棋盘上的棋子拿走到只剩下一个且位置和初始空白位置相同.输出几步和每步的起始与落子位置.输出字典序最小的解,无解输出IMPOSSIBLE. 题目分析: 可以直接BFS计算. 但是状态太多,需要进行状态压缩. 将当前状态用二进制保存. 每个点最多可以有六种

1533 Moving Pegs[暴力+打表]

这个题不是很难,就是暴力模拟一下,利用二进制表示状态,反正最后一共15种结果,暴力程序跑慢点也没事~,2个程序一个250行的暴力,一个150行的表,也是蛮拼的.. 14933000 1533 Moving Pegs Accepted C++ 0.009 2015-02-06 03:15:36 暴力程序: #include<cstdio> #include<queue> #include<set> #include<cstring> #include<a

HDU 4012 Paint on a Wall(BFS+位压缩)(好题)

题意:这题的意思有一个2*n的矩形,要给这个矩形涂色每次可以涂一个矩形形状的某种颜色,允许新颜色覆盖旧的颜色求最少多少步可以求出.(1<=n<=8) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4012 准备拿这题学位压缩,结果看不懂题解...,然后一气之下去学状压dp...才看懂了什么是位压缩,才看懂了这题的题解,然后自己码出来了,一题好题就这么被我水掉了... 思路:每次涂色以后必有一个格子的颜色是最终的颜色,否则这次涂色根本没意义,所以我

hdu 1429 胜利大逃亡(续)(bfs+位压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7346    Accepted Submission(s): 2546 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

UVALive 2520 Holedox Moving(BFS+状态压缩)

这个题目在比赛的时候我们是没有做出来的,但是听到他们说进制哈希的时候,感觉真的是挺高端的,于是赛后开始补题,本着我的习惯在看题解之前自己再试着写一遍,我当时存储状态的方法是string + map,我用string将蛇的各个位置都存下来,用map记录这个状态有没有出现过,当时是过了题目中给的样例,我就开始担心STL会不会超时,后来发现想多了,这个方法WA了,至于为什么,我还没明白,或许是状态的处理错误.总之我自己也觉得这个状态有点不靠谱..于是开始换用题解的方式.发现所谓的进制哈希,其实就是状态

poj1753 Flip Game(BFS+位压缩)

题目链接 http://poj.org/problem?id=1753 题意 一个棋盘上有16个格子,按4×4排列,每个格子有两面,两面的颜色分别为黑色和白色,游戏的每一轮选择一个格子翻动,翻动该格子意味着将该格子及其上下左右格子(如果存在的话)的黑面朝上变成白面朝上,反之亦然,游戏的目标是格子全部黑面朝上或者全部白面朝上.输入棋盘的初始状态,求最少经过多少轮可以达到游戏的目标. 思路 求最少轮数,我会想到使用bfs来解决(dfs也可以解决),但使用bfs求解,如果每个状态都直接存储下当前棋盘的

hdu 1429 胜利大逃亡(续)(BFS+位压缩)

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <ma

ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其到(1,1)的最短路长 题解:开始做的时候用BFS暴力做了一次,结果RE了,后来看了其他的题解和discuss才转向状态压缩.也看到有人用A*做出来了. 现在简要介绍一下状态压缩的思路: 由于蛇身最长只有8,可以利用两条相邻蛇身坐标确定其相对方向(四个方向),两位二进制可以表示 这样 一个蛇头坐标+

uva 11195 Another queen (用状态压缩解决N后问题)

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2136 Problem A Another n-Queen Problem I guess the n-queen problem is known by every person who has studied backtracking. In this problem you s