2018 ACM-ICPC北京网络赛 A.Saving Tang Monk II(bfs)

好久没bfs了,没想到用三维数组去标记状态来进行bfs。。。但仔细一想想,这么解很有道理。。。

因为这个图每个格子可以走多遍,我们考虑,对于一个格子,如果带着相同的氧气瓶走两次,那结果是相同的。所以我们从这个约束进行搜索,开一个三位数字,vis[i][j][k]代表带着k个氧气瓶走到第[i][j]个格子。然后就是进行讨论。

我们要求到达终点的时间最短,所以可以用优先队列进行bfs,首先到达终点的肯定是时间最短的。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int vis[150][150][6];
int dis[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
char ma[150][150];
int n,m;
struct Node
{
    int x;
    int y;
    int t;
    int b;
    Node(int xx=0,int yy=0,int tt=0,int bb=0):x(xx),y(yy),t(tt),b(bb) {}
    bool operator <(const Node &a)const
    {
        return t>a.t;
    }
};//优先队列按时间递增排序。
priority_queue<Node>Q;
int xt,yt;
int bfs()
{
    Node top;
    int tx,ty;
    while(!Q.empty())
    {
        //cout<<"---"<<endl;

        top=Q.top();
        //cout<<top.x<<" "<<top.y<<endl;
        Q.pop();

        for(int i=0; i<4; i++)
        {
            tx=top.x+dis[i][0];
            ty=top.y+dis[i][1];
            if(tx>=1&&tx<=n&&ty>=1&&ty<=m)
            {//cout<<"+++"<<tx<<" "<<ty<<" "<<top.b<<" "<<vis[tx][ty][top.b-1]<<endl;
                if(ma[tx][ty]=='#')
                {
                    if(top.b<1)continue;//没有氧气瓶不能进入毒气室
                }
               if(ma[tx][ty]=='#'&&top.b>=1&&!vis[tx][ty][top.b-1])//可以进入
                {
                    vis[tx][ty][top.b-1]=1;//标记状态 不用重复搜索
                    Q.push(Node(tx,ty,top.t+2,top.b-1));//时间增加2,用掉一个氧气瓶
                }
                if(ma[tx][ty]=='.'&&!vis[tx][ty][top.b])
                {
                    vis[tx][ty][top.b]=1;
                    Q.push(Node(tx,ty,top.t+1,top.b));
                }
                if(ma[tx][ty]=='P'&&top.t>=0&&!vis[tx][ty][top.b])
                {
                     vis[tx][ty][top.b]=1;
                    Q.push(Node(tx,ty,top.t,top.b));//因为是P,所以不需要时间
                }
                if(ma[tx][ty]=='B'&&top.b<5&&!vis[tx][ty][top.b+1])//最多只能带5个,需要判断
                {
                     vis[tx][ty][top.b+1]=1;
                    Q.push(Node(tx,ty,top.t+1,top.b+1));
                }
                if(ma[tx][ty]=='S'&&!vis[tx][ty][top.b])//注意S可以重复走
                {
                     vis[tx][ty][top.b]=1;
                    Q.push(Node(tx,ty,top.t+1,top.b));
                }
                if(ma[tx][ty]=='T')
                {
                    return top.t+1;
                }

            }
        }
    }
    return -1;
}
int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)break;
        memset(vis,0,sizeof(vis));
        while(!Q.empty())Q.pop();
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                cin>>ma[i][j];
                if(ma[i][j]=='S')
                {
                    Q.push(Node(i,j,0,0));
                    vis[i][j][0]=1;
                }
                if(ma[i][j]=='T')
                {
                    xt=i;
                    yt=j;
                }
            }
        }
        int ans=bfs();
        printf("%d\n",ans);
    }
}

import pymysql
def conn():
  con=pymysql.connect(
    host='127.0.0.1',
    port=3308,
    user='root',
    password='tiger',
    db='student',
    charset='utf8'
    )
  cursor = con.cursor()

# SQL 查询语句
  sql = "SELECT * FROM course"
  try:
    
   # 执行SQL语句
    cursor.execute(sql)
   # 获取所有记录列表
    results = cursor.fetchall()
    print ("学号 姓名 年龄")
    for it in results:
        for i in range(len(it)):
            print (it[i],' ')
        print ('\n')
  except:
    print ("Error: unable to fecth data")

# 关闭数据库连接
  cursor.close()
  conn.close()

conn()
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值