51Nod-1572-宝岛地图

来源:互联网 发布:腾讯云阿里云哪个好 编辑:程序博客网 时间:2024/04/29 21:12

ACM模版

描述

描述
描述

题解

这个问题一开始我选择暴力,结果 TLE 了,然后各种优化,考虑到很多位置是重复判断的,所以我选择将所有可能会路过的相对坐标存在 set 中,结果依然是 TLE 了两组,虽然时间上快了很多,但是依然无法避免的超时了(代码 One)。

然后,发现自己虽然在不断地优化,但是始终没有摆脱暴力的思路,这里应该将有障碍的地方全部设置为 1,然后求前缀和,因为如果我们一步一步的去判断肯定会超时,我们应该一个指令一个指令去判断,每一个指令都是一个矩形的位移,所以我们可以根据前缀和来实现一下子判断(代码 Two)~~~

我竟然一开始没有想到这种优化,脑子被驴踢了,一个三级题难为我那么久……

代码

One:

/*//  TLE#include <iostream>#include <cstdio>#include <cstring>#include <set>using namespace std;const int MAXN = 1010;const int MAX_LETTER = 26;const int MAX_ORDER = 1e5 + 10;int n, m, k;char map[MAXN][MAXN];struct node{    int x, y;} L[MAX_LETTER];struct order{    char dir;    int steps;} O[MAX_ORDER];set<pair<int, int> > spii;set<pair<int, int> >::iterator it;void charge(int x, int y){    for (int i = 0; i < k; i++)    {        for (int j = 0; j < O[i].steps; j++)        {            if (O[i].dir == 'N')            {                x -= 1;            }            else if (O[i].dir == 'S')            {                x += 1;            }            else if (O[i].dir == 'E')            {                y += 1;            }            else if (O[i].dir == 'W')            {                y -= 1;            }            spii.insert(make_pair(x, y));        }    }}int charge_(int x, int y){    int a, b;    for (it = spii.begin(); it != spii.end(); it++)    {        a = x + it->first;        b = y + it->second;        if (a < 0 || a >= n || y < 0 || y >= m || map[a][b] == '#')        {            return 0;        }    }    return 1;}int main(int argc, const char * argv[]){    memset(L, -1, sizeof(L));    cin >> n >> m;    for (int i = 0; i < n; i++)    {        scanf("%s", map[i]);        for (int j = 0; j < m; j++)        {            if (map[i][j] >= 'A' && map[i][j] <= 'Z')            {                int k = map[i][j] - 'A';                L[k].x = i;                L[k].y = j;            }        }    }    cin >> k;    char dir[3];    for (int i = 0; i < k; i++)    {        scanf("%s%d", dir, &O[i].steps);        O[i].dir = dir[0];    }    int x = 0, y = 0;    spii.insert(make_pair(0, 0));    charge(x, y);    int flag = 0;    for (int i = 0; i < MAX_LETTER; i++)    {        if (L[i].x != -1)        {            if (charge_(L[i].x, L[i].y))            {                cout << (char)(i + 'A');                flag = 1;            }        }    }    if (flag == 0)    {        cout << "no solution";    }    puts("");    return 0;}*/

Two:

#include <algorithm>#include <iostream>#include <cstdio>using namespace std;const int MAXN = 1010;const int MAX_LETTER = 26;const int MAX_ORDER = 1e5 + 10;struct node{    int x, y;} L[MAX_LETTER];struct order{    char dir;    int steps;} O[MAX_ORDER];int n, m, k;char s[MAXN];int map[MAXN][MAXN];bool ok(int x, int y){    return x > 0 && y > 0 && x <= n && y <= m;}int Sum(int a, int b, int c, int d){    return map[a - 1][b - 1] + map[c][d] - map[a - 1][d] - map[c][b - 1];}bool charge(int x, int y){    for (int i = 1; i <= k; i++)    {        if (O[i].dir == 'N')        {            if (!ok(x - O[i].steps, y))            {                return 0;            }            if (Sum(x - O[i].steps, y, x, y))            {                return 0;            }            x = x - O[i].steps;        }        if (O[i].dir == 'S')        {            if (!ok(x + O[i].steps, y))            {                return 0;            }            if (Sum(x, y, x + O[i].steps, y))            {                return 0;            }            x = x + O[i].steps;        }        if (O[i].dir == 'W')        {            if (!ok(x, y - O[i].steps))            {                return 0;            }            if (Sum(x, y - O[i].steps, x, y))            {                return 0;            }            y = y - O[i].steps;        }        if (O[i].dir == 'E')        {            if (!ok(x, y + O[i].steps))            {                return 0;            }            if (Sum(x, y, x, y + O[i].steps))            {                return 0;            }            y = y + O[i].steps;        }    }    return 1;}int main(){    cin >> n >> m;    for (int i = 1; i <= n; i++)    {        scanf("%s", s + 1);        for (int j = 1; j <= m; j++)        {            if (s[j] == '#')            {                map[i][j] = 1;            }            else if (s[j] >= 'A' && s[j] <= 'Z')            {                int k = s[j] - 'A';                L[k].x = i;                L[k].y = j;            }        }    }    for (int i = 1; i <= n; i++)    {        for (int j = 1; j <= m; j++)        {            map[i][j] = map[i][j] + map[i - 1][j] + map[i][j - 1] - map[i - 1][j - 1];        }    }    cin >> k;    for (int i = 1; i <= k; i++)    {        scanf("%s%d", s, &O[i].steps);        O[i].dir = s[0];    }    int flag = 0;    for (int i = 0; i < MAX_LETTER; i++)    {        if (L[i].x && charge(L[i].x, L[i].y))        {            putchar(i + 'A');            flag = 1;        }    }    if (!flag)    {        cout << "no solution";    }    putchar(10);    return 0;}