您的位置:首页 > 其它

hdu 3500 Fling (DFS+方法)

2015-11-09 20:27 357 查看
原题链接:

hdu 3500

题目大意:

7*8棋盘

不超过12个小球

以一个球击另一个球的方式将球击出棋盘,胜利的条件:最后只剩一个球。

1.两个球紧挨着推不动。

2.球会停在碰到下一个球时的位置。(例如:从左边击中球(3,4),则原球会停在(3,3))

3.不考虑动能损耗。

4.如果有多种情况就按照越左上角越好和U,L,R,D的优先级输出优先级最高的情况。(copy的,表示看不懂)

思路:

从第一个小球开始按“ULRD”的顺序搜索,DFS往下搜索第一种可能的情况。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int MAXN=15;
char G[MAXN][MAXN];
const int next[][2]={{-1,0},{0,-1},{0,1},{1,0}};
const char * dir="ULRD";

int ans[MAXN];//记录小球被推下去的顺序
char ansdir[MAXN];//记录小球被推下去时的方向
int sum;//记录有多少个小球

bool check(int x,int y)
{
if(x>=0&&x<7&&y>=0&&y<8)
return true;
return false;
}

bool DFS(int num)
{
if(num==sum-1)
return true;
for(int i=0;i<7;i++)
{
for(int j=0;j<8;j++)
{
if(G[i][j]=='O')
{
for(int k=0;k<4;k++)
{
bool ishave=false;
int fx[MAXN];
int fy[MAXN];
int fs=0;
int tx=i+::next[k][0];
int ty=j+::next[k][1];
if(check(tx,ty)&&G[tx][ty]=='O')continue;//相邻的两个小球推不动
while(check(tx,ty))//记录下该方向上所有的小球
{
if(G[tx][ty]=='O')
{
ishave=true;
fx[fs]=tx;
fy[fs]=ty;
fs++;
}
tx+=::next[k][0];
ty+=::next[k][1];
}
if(ishave)//判断该方向上是否有小球
{
G[i][j]='X';
for(int h=0;h<fs;h++)//移动该方向上小球的位置
{
G[fx[h]][fy[h]]='X';
G[fx[h]-::next[k][0]][fy[h]-::next[k][1]]='O';
}
ans[num]=i*8+j;
ansdir[num]=dir[k];

if(DFS(num+1))//有正确答案就返回
return true;
G[i][j]='O';
tx=i+::next[k][0];
ty=j+::next[k][1];
while(check(tx,ty))//该方向上的小球全部清除
{
if(G[tx][ty]=='O')
{
G[tx][ty]='X';
}
tx+=::next[k][0];
ty+=::next[k][1];
}
for(int h=0;h<fs;h++)//恢复小球原来的位置
{
// G[fx[h]-::next[k][0]][fy[h]-::next[k][1]]='X';
G[fx[h]][fy[h]]='O';

}

}
}

}
}
}
return false;
}

int main()
{
int kase=0;
while(scanf("%s",G[0])!=EOF)
{
sum=0;
for(int i=1;i<7;i++)
scanf("%s",G[i]);
for(int i=0;i<7;i++)
for(int j=0;j<8;j++)
if(G[i][j]=='O')
sum++;
DFS(0);
if(kase++)
printf("\n");
printf("CASE #%d:\n",kase);
for(int i=0;i<sum-1;i++)
{
printf("%d %d %c\n",ans[i]/8,ans[i]%8,ansdir[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: