[ACdream]瑶瑶带你玩激光坦克

Problem Description

有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来达到一些目的,激光可以通过一些镜子反射。

机智的瑶瑶为了显示自己的智商高于常人,把这个游戏改造了一下,变成了用激光攻击敌人的游戏。

瑶瑶想知道射一次激光最多可以攻击到多少个敌人。

PS: 由于激光很强大,可以在击中敌人后穿过它,而瑶瑶自己的坦克由于有特殊装置,所以不会被激光击中,激光也会直接穿过它

Input

第1行两个正整数n, m (1 ≤ n, m ≤ 1000)表示地图大小,接下来n行每行m个字符描述地图。

表示此处为空地

表示此处为障碍(激光不可穿过,激光路径打到障碍时就结束)

代表瑶瑶的坦克位置

代表敌人

代表按 左下-右上 放置的镜子

代表按 左上-右下 放置的镜子

Output

一个整数代表瑶瑶向某个方向发射激光后最多可以攻击到的敌人数。

Sample Input
5 5
.*/E\
E*.*.
E*TEE
\.../
.*\EE
Sample Output
4

集体思路:
由于数据500*500=250000过大,不能用递归,否则RE,所以只能查找四个方向并标记,比较四个方向的最大值,由于有可能出现陷入死循环的可能,所以每次遇到E都要标记一下,然后下次遇到了直接跳过。这题就是判断遇到" \ "以及 ” / ".后如何判断方向的问题了,每一次查找一个就用另外一个数组标记一下,结束条件就是 遇到 “*” 的以及已经标记的,还有就是不在范围内。
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include<iostream>
using namespace std;
#define Clear(A, X) memset (A, X, sizeof A)

const int maxG = 1005;
int path[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//down, up, right, left
char G[maxG][maxG];
int sr, sc, n, m;
int vis[maxG][maxG][4], flag[maxG][maxG];

int stop (int nx, int ny, int way)
{
    if (nx < 0 || nx >= n || ny < 0 || ny >= m) return 1;
    if (G[nx][ny] == '*') return 1;
    if (vis[nx][ny][way]) return 1;
    return 0;
}
int GO (int way)
{
    Clear (vis, 0);
    Clear (flag, 0);
    int x = sr, y = sc, nx, ny, ans = 0;
    while (!stop (x, y, way))
    {
        vis[x][y][way] = 1;
        if (G[x][y] == '\\' && way == 0) way = 2;//down -> right
        else if (G[x][y] == '\\' && way == 1) way = 3;//up -> left
        else if (G[x][y] == '\\' && way == 2) way = 0;//right -> down
        else if (G[x][y] == '\\' && way == 3) way = 1;//left -> up
        else if (G[x][y] == '/'  && way == 0) way = 3;//down -> left
        else if (G[x][y] == '/'  && way == 1) way = 2;//up -> right
        else if (G[x][y] == '/'  && way == 2) way = 1;//right ->up
        else if (G[x][y] == '/'  && way == 3) way = 0;//left -> down
        if (G[x][y] == 'E' && !flag[x][y]) ++ ans, flag[x][y] = 1;
        x+= path[way][0];
        y+= path[way][1];
    }
    return ans;
}
int main ()
{
    scanf ("%d%d", &n, &m);
    int ans = 0;
    for(int i=0; i<n; i++) scanf("%s",G[i]);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(G[i][j]=='T')
            {
                G[i][j]='.';
                sr=i;sc=j;
                break;
            }
        }
    }
    for (int i = 0; i < 4; ++ i) ans = max (ans, GO (i));
    printf ("%d\n", ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/gaojupeng/p/4448246.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前台: (1)注册登录模块:按照学校的相关规定进行注册和登录。 (2)招聘信息查看:高校毕业生们可以网站首页上查看所有的招聘信息,除此之外还可以输入公司名称或岗位名称进行搜索。 (3)用人单位模块:此模块为宣传用人单位的主要功能模块,具体包括用人单位简介、岗位需求及职责及公司介绍等功能。 (4)就业指导:学生朋友们在就业前可以通过此模块获取指导。 (5)新闻信息:为了让用户们可以了解到最新的新闻动态,本系统可以通过新闻信息查看功能阅读近期的新闻动态。 (6)在线论坛:毕业季的同学们可以通过此模块相互交流。 后台: (1)系统用户管理模块:可以查看系统内的管理员信息并进行维护。 (2)学生管理模块:通过此功能可以添加学生用户,还可以对学生信息进行修改和删除。 (3)用人单位管理模块:管理员用户通过此模块可以管理用人单位的信息,还可以对用人单位信息进行查看和维护。 (4)招聘管理模块:管理员通过此功能发布和维护系统内的照片信息。 (5)就业指导管理模块:通过此模块可以编辑和发布就业指导信息,从而更好的帮助就业季的同学们。 (6)论坛管理:通过论坛管理可以查看论坛中的主题帖及里面的回复信息,除此之外还可以对论坛中的信息进行维护和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值