HDOJ 3500 Fling

Fling

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 460    Accepted Submission(s): 192


Problem Description
Fling is a kind of puzzle games available on phone.
This game is played on a board with 7 rows and 8 columns. Each puzzle consists of a set of furballs placed on the board. To solved a puzzle, you need to remove the furballs from board until there is no more than one furball on the board. You do this by ´flinging´ furballs into other furballs, to knock them off the board. You can fling any furballs in four directions (up, left, right, down). The flung furball stops at the front grid of another one as soon as knocking it. And the knocked furball continues to rolling in the same direction until the last knocked one goes off the board. For instance, A furball at (0, 0) rolls right to the furball at (0, 5), then it will stop at (0, 4). Moreover, the latter will roll to right. You cannot fling a furball into a neighbouring furball, the one next to in any of four directions. However, it is permitted for a rolling ball knocks into a ball with a neighbour in that direction.
Input
The input contains multiple test cases.
For each case, the 7 lines with 8 characters describe the board. ´X´ represents a empty grid and ´O´ represents a grid with a furball in it. There are no more than 12 furballs in any board.
Each case separated by a blank line.

 

Output
For each case, print a line formatted as "CASE #NUM:", where NUM is the number of current case.
Then every ´fling´ prints a line. Each line contains two integers X, Y and a character Z. The flung furball is located at grid (X, Y), the top-left grid is (0, 0). And Z represents the direction this furball towards: U (Up), L (Left), R (Right) and D (Down);
Print a blank line between two cases.
You can assume that every puzzle could be solved.
If there are multiple solve sequences, print the smallest one. That is, Two sequences A (A1, A2, A3 ... An) and B (B1, B2, B3 ... Bn). Let k be the smallest number that Ak != Bk.
Define A < B :
(1) X in Ak < X in Bk;
(2) Y in Ak < Y in Bk and X in Ak = X in Bk;
(3) Z in Ak < Z in Bk and (X,Y) in Ak = (X,Y) in Bk;
The order of Z: U < L < R < D.

 

Sample Input
  
  
XXXXXXXX XXOXXXXX XXXXXXXX XXXXXXXX XOXXXXOX XXXXXXXX XXXXXXXX XXXXXXXX XOXOXOOX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
 

Sample Output
  
  
CASE #1: 4 6 L 1 2 D CASE #2: 1 1 R 1 4 L 1 3 R

游戏规则还是自己玩了几次才懂的,整理一下思路,明确解题思路是DFS,思路就是每次搜索O点判断,能否移动,如果移动,保存状态,更新路径,按照规则更新地图,然后传入下一个DFS(步数),回溯上一个状态,即不走不移动这个点;搜索下一个方向,挺不错的题,自己过程有点不清楚参考了别人的代码,唉,智商还是不足,代码能力太弱了,将过程用代码实现还是有点困难;

#include<stdio.h>
#include<string.h>
int dir[4][2]={-1,0,0,-1,0,1,1,0};    //方向数组,因为有优先级,所以方向数组的确定表示优先级
char turn[4]={'U','L','R','D'};     //四个方向
char map[7][8];
int num,flag;
int case1=0;
int move;
int check(int x,int y)           //边界出来
{
    if(x<7&&x>=0&&y<8&&y>=0)
        return 1;
    else
        return 0;
}
struct node
{
    int x;
    int y;
    int d;
}path[200];                    //path用来记录的是从游戏开始到游戏结束的整条路径x,y坐标 d表示怎么转
void DFS(int count)           //count记录步数
{
    if(count==num)          //如果所有的O都出去了只剩下一个;就证明游戏结束;
    {
        flag=1;
        return;
    }
    for(int i=0;i<7;i++)           //每走一步后,搜索整个图的O,看这个O能否进行移动;
    {
        for(int j=0;j<8;j++)
        {
            if(map[i][j]=='O')
            {
                move=0;
                for(int k=0;k<4;k++)    //搜索相邻四个方向上的O;
                {
                    int dx=i+dir[k][0];
                    int dy=j+dir[k][1];
                    if(map[dx][dy]=='O'&&check(dx,dy))  //如果相邻的有O,这个方向就不能移动,就进行下一个方向;
                        continue;
                    while(check(dx,dy))    //每个方向一直走到底;
                    {
                        dx=dx+dir[k][0];
                        dy=dy+dir[k][1];
                        if(map[dx][dy]=='O'&&check(dx,dy)) //如果该方向上面存在另外一个O;
                        {
                            move=1;                       //可以移动
                            map[dx][dy]='X';              //将这个O变为X
                            map[dx-dir[k][0]][dy-dir[k][1]]='O';    //把这个O的前面一个X变成O‘,如果有两个及其以上的O,就类似于传递动能,依次传下去,但起始的O还是会停在第一个O前面,
                        }
                    }
                    if(move)           //如果存在能够移动的;开始移动并记录
                    {
                        map[i][j]='X';     //初始O变成X
                        path[count].x=i;    //记录;
                        path[count].y=j;
                        path[count].d=k;
                        DFS(count+1);     //下一步DFS;
                        
                        if(flag==1)
                            return;
                        dx=dx-dir[k][0];      //如果不走这一步进行回溯;
                        dy=dy-dir[k][1];
                        while(dx!=i||dy!=j)    //一直回到起始点
                        {
                            if(map[dx][dy]=='O')   //如果存在变化后的O
                            {
                                map[dx][dy]='X';       //回溯改为X;
                                map[dx+dir[k][0]][dy+dir[k][1]]='O';   //回溯成O
                            }
                            dx=dx-dir[k][0];        //继续回
                            dy=dy-dir[k][1];
                        }
                        map[i][j]='O';     //起始回溯为O;
                    }
                }
            }
        }
    }
}
int main()
{
    while(scanf("%s",map[0])!=EOF)
    {
        case1++;
        for(int i=1;i<7;i++)
            scanf("%s",map[i]);
        num=0;
        flag=0;
        for(int i=0;i<7;i++)
        {
            for(int j=0;j<8;j++)
            {
                if(map[i][j]=='O')
                    num++;
            }
        }
        DFS(1);
        if(case1!=1)
            printf("\n");
        printf("CASE #%d:\n",case1);
        for(int i=1;i<num;i++)
        {
            printf("%d %d %c\n",path[i].x,path[i].y,turn[path[i].d]);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值