搜索 HOJ 1749 Doggone Moles

本文解析了一道经典的ACM竞赛题目——捉鼹鼠问题。该题要求通过追踪猎犬的移动来推断鼹鼠可能的位置。文章详细介绍了题目的背景设定、输入输出格式,并提供了一份完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Doggone Moles

My Tags  (Edit)
Source : ACM ICPC Mid-Atlantic Regional Contest 2004
Time limit : 1 secMemory limit : 32 M

Submitted : 22, Accepted : 11

A mole has pockmarked our yard with a rectangular grid of tunnels. Infuriated at the damage, we have released a number of terriers into the yard to catch the mole. The terriers have very sensitive hearing and, if they come close enough to the mole, can dig very quickly and catch the rodent. Unfortunately, the mole is very sensitive to the vibrations caused by the footsteps of the terriers, and will actively try to evade them.

We have no idea where the mole was when the terriers were released. But we have watched the terriers move about the yard for some time, and the mole has not been caught. Write a program that deduces where the mole might be, given our observations.

At the time we began recording our observations, we also know that the mole was not in a position underneath or adjacent to a terrier. In each subsequent time interval, the terriers may have remained in the same position or may have moved one space horizontally or vertically. Then the mole may have done the same. If, before or after any of these moves, by terriers or by the mole, a terrier were directly over the mole or in a position adjacent (horizontally or vertically) to the mole, the mole would have been caught.

Write a program that accepts a description of the yard and of the location of the terriers within it over a period of time. The program should print a list of the possible positions of the mole at the end of that time.

Input

The input for this program consists of one or more observation sets. Each observation set is constructed as follows:

  • The first line contains 4 integers 
    <W> <L> <N> <T> 
    W and L are positive integers representing the width (x dimension) and length (y dimension) of the yard. N is the non-negative number of terriers. T is the positive number of time intervals over which we have conducted observations.
  • The remainder of the observation set contains one line per terrier. Each line contains 2T integers denoting the (x,y) coordinates of the terrier at each of the T time steps, expressed separated by whitespace without parentheses or commas. Possible coordinates range from (0, 0) in one corner of the yard to (W, L) at the opposite corner.

The end of input is signaled by a line containing 4 zeros in place of a valid (W, L, N, T) set.

Output

For each observation set, your program should print a line ”Observation Set ” followed by the integer number of the set (starting at 1).

If there is at least one possible location for the mole, then, beginning on the next line, print all the possible locations of the mole as (x, y) pairs, 8 pairs per output line (except possibly fewer for the final line of output for the set). There should be no leading blanks before the first pair on a line nor trailing blanks after the final pair on the line, but successive pairs on the same line should be separated by exactly one blank. A pair is printed in the format “(x, y)” with no internal blanks. Pairs should be printed in an order such that pairs with lower values of y come before any pairs with higher values of y and, for pairs with the same y value, pairs with lower values of x come before pairs with higher values of x.

If there are no possible locations for the mole, then the second line of output for the observation set will consist of the message “No possible locations”.

Sample Input

1 4 2 3
1 1  1 2  1 3
0 1  0 2  0 3
6 2 2 4
3 0  3 1  4 1  4 0
3 1  3 1  4 1  3 1
0 0 0 0

This input set may be visualized as:

搜索  HOJ 1749 Doggone Moles - 恶魔仁 - 恶魔仁

Sample Output

Observation Set 1
No possible locations
Observation Set 2
(0,0) (1,0) (2,0) (6,0) (0,1) (1,1) (5,1) (6,1)
(0,2) (1,2) (2,2) (4,2) (5,2) (6,2)

题意:有一个农场要捉mole,如果terriers在他旁边或者在它的位置,那么mole就马上被抓住了。求出处经过T时间,mole可能在的位置。

思路:首先这个题目里面,mole和terrirers不是同时运动的。。。这个坑了我很久,terrier先走,如果mole在旁边,就被抓住了,没被抓住,mole才能走。。。。我们用三维数组表示T时间内能去的地方,然后从T=0开始一个一个位置进行dfs,把走到最后的位置记录下来就行了。

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define mp make_pair
int W,L,T,N;
int Move[2][4] = { { -1 , 0 , 1 , 0 } , { 0 , 1 , 0 , -1 } };

bool cango[210][210][210];
bool vis[210][210][210];
struct Ans
{
        Ans(int xx = -1 , int yy = -1) : x (xx) , y (yy) { }
        int x , y;
}ans[110*110];
int top;

bool cmp(const Ans & a1 , const Ans & a2)
{
        if (a1.y==a2.y) return a1.x > a2.x;
        return a1.y > a2.y;
}

inline bool inRange(int r,int c)
{
        if (r < 0 || r > L || c < 0 || c > W) return false;
        return true;
}


void init()
{
        memset(cango,0x3f,sizeof(cango));
        memset(vis,0,sizeof(vis));
        top = 0;
}

void input()
{
        for (int i = 0 ; i < N ; ++i)
        {
                int r , c;
                for (int j = 0 ; j < T ; ++j)
                {
                        scanf("%d%d",&c,&r);
                        cango[j][r][c] = false;
                        for (int k = 0 ; k < 4 ; ++k)
                        {
                                int rr = r+Move[0][k];
                                int cc = c+Move[1][k];
                                if (!inRange(rr,cc)) continue;
                                cango[j][rr][cc] = false;
                        }
                }
        }
}

void dfs(int t,int r,int c)
{
        if (!cango[t+1][r][c] || vis[t][r][c]) return;
        if (t==T-1)
        {
                vis[t][r][c] = true;
                ans[top++] = Ans(c,r);
                return;
        }
        if (cango[t+1][r][c] && !vis[t+1][r][c]) dfs(t+1,r,c);
        for (int i = 0 ; i < 4 ; ++i)
        {
                int rr = r + Move[0][i];
                int cc = c + Move[1][i];
                if (!inRange(rr,cc) || !cango[t+1][rr][cc] || vis[t+1][rr][cc]) continue;
                dfs(t+1,rr,cc);
        }
        vis[t][r][c] = true;
}

void solve()
{
        for (int r = 0 ; r <= L ; ++r)
        {
                for (int c = 0 ; c <= W ; ++c) if (cango[0][r][c])
                {
                        dfs(0,r,c);
                }
        }
        sort(ans,ans+top,cmp);
        int cnt = 0;
        if (top)
        {
                Ans tmp = Ans(-1,-1);
                while (top)
                {
                        tmp = ans[--top];
                        if (cnt) printf(" ");
                        printf("(%d,%d)",tmp.x,tmp.y);
                        ++cnt;
                        if (cnt==8) 
                        {
                                printf("\n");
                                cnt = 0;
                        }
                }
        }
        else 
                printf("No possible locations\n");
        if (cnt) cout << endl;
}

int main()
{
        int Cas = 0;
        while (scanf("%d%d%d%d",&W,&L,&N,&T) , N+T+W+L)
        {
                ++Cas;
                init();
                input();
                printf("Observation Set %d\n",Cas);
                solve();
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值