July 15th 模拟赛C T4 回家(莫名其妙【推荐】) Solution

来源:互联网 发布:逆波兰式计算c语言 编辑:程序博客网 时间:2024/06/10 08:56

空降题目处
点我点我点我

Description:

Alice住在森林里,森林可以看作是N*M的网格,森林里有怪兽,用‘.’表示空地,‘+’表示怪兽,‘V’表示Alice现在的位置,‘J’表示Alice的家。
Alice可以从当前单元格向上下左右相邻单元格移动,有怪兽的地方也可以走,只不过比较危险,有怪兽的单元格对其他单元格会产生一定的危险系数,假设怪兽位置为(A,B),它对某单元格(R,C)的危险系数为:|R-A|+|C-B|,危险系数越小越危险,每个单元格的危险系数是所有怪兽对它产生的系数的最小值。
Alice请你帮她找一条最佳路径回家,即使得路径上经过单元格的最小的危险系数最大。

Input

输入第一行包含两个整数N和M(1<=N,M<=500),表示森林的大小。
接下来N行每行包含M个字符:‘.’,‘+’,‘V’,‘J’。
输入只包含一个‘V’和‘J’,而且至少有一个‘+’。

Output

输出最佳路径中最小的危险系数。

Solution

将Monster的位置存入队列,作为初始状态,利用SPFA更新出矩阵的危险系数. (危险系数越大越安全?智障?)
二分答案,利用Bfs检索合法性.

Program

C++

#include<iostream>#include<fstream>#include<cstdio>#include<cmath>#include<cstring>using namespace std;int n,m,sx,sy,ex,ey,t,l[501][501],d[1000001][3];string c;int me[5][3]={{0,0,0},{0,0,1},{0,1,0},{0,-1,0},{0,0,-1}};bool bj[501][501];void SPFA(int j);bool Bfs(int q);int FF(int l,int r);int main(){    memset(l,10000,sizeof(l));    scanf("%d%d\n",&n,&m);    for (int i=1;i<=n;i++)    {        cin>>c;        for (int j=1;j<=m;j++)        {            switch (c[j-1])            {                case '+':                    t++;                    d[t][1]=i;                    d[t][2]=j;                    bj[i][j]=true;                    l[i][j]=0;                break;                case 'V':                    sx=i;                    sy=j;                break;                case 'J':                    ex=i;                    ey=j;                break;            }        }        //scanf("\n");    }    SPFA(t);    printf("%d",FF(0,n+m));}void SPFA(int j){    int i=0,p,q;    while (i<j)    {        i++;        for (int k=1;k<=4;k++)        {            p=d[i][1]+me[k][1];            q=d[i][2]+me[k][2];            if ((p>0)&&(p<n+1)&&(q>0)&&(q<m+1))            {                if (l[d[i][1]][d[i][2]]+1<l[p][q])                {                    l[p][q]=l[d[i][1]][d[i][2]]+1;                    if (!bj[p][q])                    {                        j++;                        d[j][1]=p;                        d[j][2]=q;                        bj[p][q]=true;                    }                }            }        }        bj[d[i][1]][d[i][2]]=false;    }}bool Bfs(int q){    int i,j,x,y;    memset(bj,false,sizeof(bj));    if (l[sx][sy]<q)        return false;    d[1][1]=sx;    d[1][2]=sy;    bj[sx][sy]=true;    i=0;    j=1;    while (i<j)    {        i++;        for (int k=1;k<=4;k++)        {            x=d[i][1]+me[k][1];            y=d[i][2]+me[k][2];            if ((x>0)&&(x<n+1)&&(y>0)&&(y<m+1)&&(l[x][y]>=q)&&(!bj[x][y]))            {                bj[x][y]=true;                j++;                d[j][1]=x;                d[j][2]=y;                if ((ex==x)&&(ey==y))                    return true;            }        }    }    return false;}int FF(int l,int r){    if (l>=r)        return l;    int m=(l+r)/2+1;    if (Bfs(m))        return FF(m,r);    else        return FF(l,m-1);}

Pascal

uses    math;var    n,m,i,j,k,sx,sy,ex,ey,t:longint;    l:array [1..500,1..500] of longint;    d:array [1..1000000,1..2] of longint;    me:array [1..4,1..2] of longint=((0,1),(1,0),(-1,0),(0,-1));    bj:array [1..500,1..500] of boolean;    c:char;procedure SPFA(j:longint);var    i,k,p,q:longint;begin    i:=0;    while i<j do    begin        inc(i);        for k:=1 to 4 do        begin            p:=d[i][1]+me[k][1];            q:=d[i][2]+me[k][2];            if (p>0) and (p<n+1) and (q>0) and (q<m+1) then            begin                if l[d[i][1]][d[i][2]]+1<l[p][q] then                begin                    l[p][q]:=l[d[i][1]][d[i][2]]+1;                    if not bj[p][q] then                    begin                        inc(j);                        d[j][1]:=p;                        d[j][2]:=q;                        bj[p][q]:=true;                    end;                end;            end;        end;        bj[d[i][1]][d[i][2]]:=false;    end;end;function Bfs(q:longint):boolean;var    i,j,k,x,y:longint;begin    fillchar(bj,sizeof(bj),false);    if l[sx][sy]<q then        exit(false);    d[1][1]:=sx;    d[1][2]:=sy;    bj[sx][sy]:=true;    i:=0;    j:=1;    while i<j do    begin        inc(i);        for k:=1 to 4 do        begin            x:=d[i][1]+me[k][1];            y:=d[i][2]+me[k][2];            if (x>0) and (x<n+1) and (y>0) and (y<m+1) and (l[x][y]>=q) and (not bj[x][y]) then            begin                bj[x][y]:=true;                inc(j);                d[j][1]:=x;                d[j][2]:=y;                if (ex=x) and (ey=y) then                    exit(true);            end;        end;    end;    exit(false);end;function find(l,r:longint):longint;var    m:longint;begin    if l>=r then        exit(l);    m:=(l+r) shr 1+1;    if Bfs(m) then        exit(find(m,r))    else        exit(find(l,m-1));end;begin    assign(input,'init.in');    reset(input);    fillchar(l,sizeof(l),$7f);    readln(n,m);    for i:=1 to n do    begin        for j:=1 to m do        begin            read(c);            case c of                '+':                begin                    inc(t);                    d[t][1]:=i;                    d[t][2]:=j;                    bj[i][j]:=true;                    l[i][j]:=0;                end;                'V':                begin                    sx:=i;                    sy:=j;                end;                'J':                begin                    ex:=i;                    ey:=j;                end;            end;        end;        readln;    end;    SPFA(t);    writeln(find(0,n+m));end.
0 1
原创粉丝点击