HDU 2531 Catch Him

Catch him 

Time Limit: 5000/1000 MS(Java/Others)

Memory Limit: 32768/32768 K(Java/Others)

[顯示標籤]

Description

在美式足球中,四分衛負責指揮整隻球隊的進攻戰術和跑位,以及給接球員傳球的任務。四分衛是一隻球隊進攻組最重要的球員,而且一般身體都相對比較弱小,所以通常球隊會安排5-7名大漢來保護他,其中站在四分衛前方、排成一線的5名球員稱爲進攻鋒線,他們通常都是135公斤左右的壯漢。

對防守方來說,攻擊對手的四分衛當然是最直接的限制對手進攻的方法。如果效果好,就可以在對方四分衛傳球之前將其按翻在地,稱之爲擒殺。擒殺是最好的鼓舞防守隊士氣的方法,因爲對方連傳球的機會都沒有,進攻就結束了,還必須倒退一些距離開球。兇狠的擒殺甚至能夠將對方的四分衛弄傷,從而迫使對方更換這個進攻核心。
在本題中,輸入給出準備擒殺四分衛的防守球員的位置、對方每個進攻鋒線球員的位置以及對方四分衛的位置,你的任務是求出這名準備擒殺的防守球員至少要移動多少步,才能夠擒殺對方四分衛。
假設對方進攻鋒線和四分衛在這個過程中都不會移動。只有1名防守球員,防守球員只要碰到對方四分衛就算擒殺。
所有的球員都是一塊連續的、不中空的2維區域。防守球員不可以從進攻鋒線的身體上穿過,也不可以從界外穿過(只能走空地)
防守隊員不可以轉動身體,只能平移。防守隊員的身體所有部分向同一個方向(上、下、左、右)移動1格的過程叫做1步。

Input

輸入包含多組數據。每組數據第一行都是兩個整數HW(0<H,W<=100),表示整個區域的高度和寬度,H=W=0表示輸入結束。接下來有H行,每行W個字符。每個字符如果是’.’,表示這裏是空地,如果是’O’,表示是進攻鋒線隊員的身體,如果是’D’,表示是準備擒殺的防守球員的身體,如果是’Q’,表示是四分衛的身體。
輸入保證符合上面的條件。防守球員的身體總共不超過20格。

Output

對每組數據,輸出包含擒殺所需最少步數的一行。如果不能擒殺,輸出帶’Impossible’的一行。

Sample Input

6 6

.Q....

QQ..OO

.OO..O

...O.O

OO.O..

....DD

7 7

.Q.....

QQ.OOO.

...O...

O......

OO..OO.

.O.....

.....DD

0 0

Sample Output

Impossible

9

 

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------

     題意:進攻鋒位和四分衛全都不會動,只有防守隊員可以動,但是,防守隊員不能轉身,身體各部分只能一起上下左右移動,不能穿過進攻鋒位。只要防守隊員能碰到四分衛,就算防守成功。

    這道題一看就是bfs,但是,與一般的bfs只採用點移動的方式不同的是,她要求以塊爲單位,進行移動和判斷操作,題中不一定是規則形狀,用描述形狀的方式行不通,所以開的結構體是塊,即用每一個點的集合來表示。

   

下面附上AC代碼:

#include<iostream>
#include<queue>
#include<cstring>
#define N 110
using namespace std;
char map[N][N];
char vis[N][N];
int h,w;
int l,r,row;
int cnt=0;
int ans;
struct body{
	int x[30],y[30];
	int step;
}start;
bool jug(body &a)
{
	int i;
	for(i=0;i<cnt;i++)
	{
		if(map[a.x[i]][a.y[i]]=='Q')
		return 1;
	}
	return 0;
}
bool check(body &a)
{
	for(int i=0;i<cnt;i++)
	{
		if(a.x[i]<0||a.y[i]<0||a.x[i]>=h||a.y[i]>=w)
		return 1;
		if(map[a.x[i]][a.y[i]]=='O')
		return 1;
	}
	if(vis[a.x[0]][a.y[0]])
		return 1;
	return 0;
}
void bfs()
{
	memset(vis,0,sizeof(vis));
	queue<body>q;
	body now,next;
	now=start;
	next=now;
	q.push(now);
	int i,j;
	vis[now.x[0]][now.y[0]]=1;

	while(!q.empty())
	{
		now=q.front();
		q.pop();
		if(jug(now))
		{
			ans=now.step;
			return;
		}
		for(i=0;i<4;i++)
		{
			if(i==0)
			{
				for(j=0;j<cnt;j++)
				{
					next.x[j]=now.x[j]+1;
					next.y[j]=now.y[j];
				}
			}
			if(i==1)
			{
				for(j=0;j<cnt;j++)
				{
					next.x[j]=now.x[j]-1;
					next.y[j]=now.y[j];
				}
			}
			if(i==2)
			{
					for(j=0;j<cnt;j++)
				{
					next.x[j]=now.x[j];
					next.y[j]=now.y[j]-1;
				}
			}
			if(i==3)
			{
				for(j=0;j<cnt;j++)
				{
					next.x[j]=now.x[j];
					next.y[j]=now.y[j]+1;
				}
			}
			if(!check(next))
			{
				vis[next.x[0]][next.y[0]]=1;
				next.step=now.step+1;
				q.push(next);
			}	
		}
	}
}
int main()
{
	while(cin>>h>>w&&h&&w)
	{
		int i,j;
		cnt=0;
		for(i=0;i<h;i++)
		{
			scanf("%s",map[i]);
			for(j=0;j<w;j++)
			if(map[i][j]=='D')
			{
				start.x[cnt]=i;
				start.y[cnt++]=j;
			}
		}
		start.step=0;
		ans=0;
		bfs();
		if(ans)cout<<ans<<endl;
		else cout<<"Impossible"<<endl;
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章