[ZOJ1144][POJ1104] Robbery

ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1144

POJ:http://poj.org/problem?id=1104

题目大意:

有大盗光顾了一个W*H的矩形城市。给出一些信息,t时刻大盗不在矩阵L,Top,Left,Right,Bottom里。

 判断大盗是否逃出去了。如果没有逃出,输出可以确定大盗的位置的时刻及该时刻大盗的位置。如果没有逃出且在任意时刻都不能确定大盗位置,输出"Nothing know."然后等着主管发飙……



解题思路:

数据范围不大, W, H, t (1 <= W,H,t <= 100)。于是决定暴力解决。

 先根据读入的ti, Li, Ti, Ri, Bi信息初始化大盗不可能存在的位置not_visit[t][x][y]。之后使用类此floodfill的思路,分别用按t正推和按t逆推将not_visit[t][x][y]填好。

之后对每一时刻t,统计not_visit[t][x][y]==0(即大盗可能存在位置)的数量记为tmp。若某一个时刻tmp==0则大盗逃出去了,输出escape。若tmp==1则在这一时刻可以确定大盗的位置。


源代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 110

int W, H, T, n;
bool notv[maxn][maxn][maxn];

bool cant(int t, int x, int y, int tadd)
{
    if (x>0 && !notv[t+tadd][x-1][y]) return false;
    if (x<W-1 && !notv[t+tadd][x+1][y]) return false;
    if (y>0 && !notv[t+tadd][x][y-1]) return false;
    if (y<H-1 && !notv[t+tadd][x][y+1]) return false;
    if (!notv[t+tadd][x][y]) return false;
    return true; 
}

int main()
{
    int cs=0, t, x1, y1, x2, y2;
    int maybe[maxn], xx[maxn], yy[maxn];
    bool escape, know;
    
    while (scanf("%d%d%d", &W, &H, &T)==3 && W && H && T)
    {
        printf("Robbery #%d:\n", ++cs);
        scanf("%d", &n);
        memset(notv, 0, sizeof(notv));
        memset(maybe, 0, sizeof(maybe));
        escape=false;
        for (int i=0; i<n; i++)
        {
            scanf("%d%d%d%d%d", &t, &x1, &y1, &x2, &y2);
            for (int x=x1-1; x<x2; x++)         //根据输入判断强盗肯定不在的位置 
                for (int y=y1-1; y<y2; y++)
                    notv[t-1][x][y]=true;
        }
        for (int t=1; t<T; t++)                             //正着一遍floodfill强盗肯定不在的位置 
            for (int x=0; x<W; x++)
                for (int y=0; y<H; y++)
                    if (!notv[t][x][y] && cant(t, x, y, -1))
                        notv[t][x][y]=true;
        
        for (int x=0; x<W; x++)
            for (int y=0; y<H; y++)
            {
                if (!notv[T-1][x][y])
                {
                    maybe[T-1]++; xx[T-1]=x; yy[T-1]=y;
                }
            }
        if (maybe[T-1]==0) escape=true;                      //判断最后时刻是否逃走,是的话结束 
        for (int t=T-2; t>=0 && !escape; t--)                 //反着一遍floodfill强盗肯定不在的位置
        {
            for (int x=0; x<W; x++)
                for (int y=0; y<H; y++)
                {
                    if (!notv[t][x][y] && cant(t, x, y, +1))
                        notv[t][x][y]=true;
                    if (!notv[t][x][y])
                    {
                        maybe[t]++; xx[t]=x; yy[t]=y;
                    }
                }
            if (maybe[t]==0) escape=true;
        }
        if (escape)
            printf("The robber has escaped.\n\n");
        else
        {
            know=false;
            for (int t=0; t<T; t++)
                if (maybe[t]==1)
                {
                    know=true;
                    printf("Time step %d: The robber has been at %d,%d.\n", t+1, xx[t]+1, yy[t]+1);
                }
            if (!know) printf("Nothing known.\n");
            printf("\n");
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值