zoukankan      html  css  js  c++  java
  • NOIP模拟题——来自风平浪静的明天

    【题目描述】
    冬眠了五年,光终于从梦中醒来。
    千咲、要,大家都在。
    隐约记得“昨天”的海船祭,爱花意外成为贡女,沉入海底。
    海面冰封,却有丝丝暖流在冰面之下涌动。
    此时,爱花沉睡在祭海女神的墓地。她的胞衣在一点点脱落,化作一簇簇暖流,夹杂着她的感情,向海面上涌去。
    爱花,你在哪里?
    五年之后,纺已经成为海洋学研究科的大学生。
    在纺的帮助下,光得知了海面下海流的情况。
    纺告诉光,暖流一旦产生,就会不断地向四周扩散,直到遇到海中的岩石。
    红腹海牛,快告诉光,爱花在哪里。
    纺帮你绘制了一张海流情况图,长度为N,宽度为M。
    海很大,一边有沙滩,一边一望无际,但长度和宽度都不会超过300。沙滩是金黄色的,所以用Y表示。海是蓝色的,所以用B表示。暖流很暖和,所以用H表示
    海中有大大小小的石头。石头很危险,所以用X表示
    光相信自己一定能找到爱花(爱花的位置只有一种可能)
    【输入格式】
    第一行包括两个整数N,M。
    接下来N行,每行M个字符。
    【输出格式】
    仅一行,表示爱花的位置(如果你无能为力,请输出 -1 ,只要你尽力,光不会责怪你)
    【样例输入】
    5 5
    YYYHB
    YYHHH
    YHHXB
    BBHBB
    BBBBB
    【样例输出】
    2 3
    【数据范围】
    对于30%的数据,n,m<=10
    对于70%的数据,n,m<=100
    对于100%的数据,n,m<=300
    【样例解释】
    在(2,3)出现第一个H后,经过3s后,出现样例输入的地图。
    P.S. Mushroom拜托他GF出的这题= =

    题目写的真好~~~~~~~~~~只是我看不懂。

    后来才晓得一开始给的图只是一个普通状态而不是最终状态(所以就误将碰到石头理解为再向下漫延一次就停下来了。。)

    正解:f[T][x][y]表示从map[x][y]开始,漫延时间为T的情况是否匹配

    (不应是H的地方出现了H则不相符,应出现H的地方没有出现H认为相符)

    YYYHB
    YYHHH
    YHHXB
    BBHBB
    BBBBB
    海流图
    YYYBB
    YYHHB
    YBHXB
    BBBBB
    BBBBB
    相符的图(蓝色部分应该出现H但没有出现)
    YYYHH
    YYHHH
    YHHXH
    BHHHB
    BBHBB
    不相符的图(红色部分不该出现H但出现了)

    于是得到DP方程:F[T][X][Y]=F[T-1][X-1][Y]&&F[T-1][X][Y-1]&&F[T-1][X+1][Y]&&F[T-1][X][Y+1]

    时间复杂度O(n³)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 const int maxn=305;
     8 char map[maxn][maxn];
     9 bool f[2*maxn][maxn][maxn];
    10 bool pd[2*maxn][maxn][maxn];
    11 char c[maxn];
    12 int n,m;
    13 bool solve(int T,int x,int y)
    14 {
    15     if(pd[T][x][y])return f[T][x][y];
    16     if(x==0||y==0)return true;
    17     if(x==n+1||y==m+1)return true;
    18     if(map[x][y]!='H')return true;
    19     if(T==0)
    20     {
    21         pd[T][x][y]=true;
    22         f[T][x][y]=true;
    23         return true;
    24     }
    25     
    26     if(map[x-1][y]=='B'||map[x+1][y]=='B'||map[x][y-1]=='B'||map[x][y+1]=='B')
    27     {
    28         pd[T][x][y]=true;
    29         f[T][x][y]=false;
    30         return false;
    31     }
    32     
    33     pd[T][x][y]=true;
    34     f[T][x][y]=solve(T-1,x-1,y)&&solve(T-1,x+1,y)&&solve(T-1,x,y-1)&&solve(T-1,x,y+1);
    35     return f[T][x][y];
    36 }
    37 int main()
    38 {
    39     freopen("calm.in","r",stdin);
    40     freopen("calm.out","w",stdout);
    41     scanf("%d%d",&n,&m);
    42     for(int i=1;i<=n;i++)
    43     {
    44         scanf("%s",c);
    45         for(int j=1;j<=m;j++)
    46         map[i][j]=c[j-1];
    47     }
    48     for(int i=1;i<=n+m;i++)
    49     for(int j=1;j<=n;j++)
    50     for(int k=1;k<=m;k++)
    51     {
    52         if(map[j][k]=='H')
    53         solve(i,j,k);
    54     }
    55     for(int i=n+m;i>=1;i--)
    56     for(int j=1;j<=n;j++)
    57     for(int k=1;k<=m;k++)
    58     {
    59         if(f[i][j][k])
    60         {
    61             printf("%d %d",j,k);
    62             return 0;
    63         }
    64     }
    65     return 0;
    66 }

    这个DP方程真心NB,考场上能想到这样做就幸福了~

  • 相关阅读:
    node03
    node02
    node01
    Vue-router重修02
    Vue-router重修01
    Vue重修02
    VUE重修01
    利用表达式目录树进行实体映射
    C#托管堆和垃圾回收
    C# 异步锁
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/6017461.html
Copyright © 2011-2022 走看看