zoukankan      html  css  js  c++  java
  • NEU710(wanghang走迷宫)

    题目链接:传送门

    题目大意:给你一个图,要从起点走到终点并且要吃够足够的金币才能出去,图上有金币(只能吃一次),

                有传送门(用一次消耗1金币,必须有金币才能使用),问最少需要多少步才能出去。不能出去输出-1

    题目思路:搜索+状态压缩技巧

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <stack>
      8 #include <cctype>
      9 #include <queue>
     10 #include <string>
     11 #include <vector>
     12 #include <set>
     13 #include <map>
     14 #include <climits>
     15 #define lson root<<1,l,mid
     16 #define rson root<<1|1,mid+1,r
     17 #define fi first
     18 #define se second
     19 #define ping(x,y) ((x-y)*(x-y))
     20 #define mst(x,y) memset(x,y,sizeof(x))
     21 #define mcp(x,y) memcpy(x,y,sizeof(y))
     22 using namespace std;
     23 #define gamma 0.5772156649015328606065120
     24 #define MOD 1000000007
     25 #define inf 0x3f3f3f3f
     26 #define N 1000010
     27 #define maxn 400005
     28 typedef pair<int,int> PII;
     29 
     30 int n,m,k,tx,ty;  ///tx ty 记录终点位置
     31 char pic[15][15];
     32 int vis[15][15][1<<5|1][6]; ///1,2维表示位置,第3维代表走到当前位置吃了哪些金币
     33 int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}}; ///第4维代表当前有多少金币
     34 int dx[10],dy[10],dcnt;  ///dcnt记录有多少传送门,前两个数组记录位置
     35 struct Node{
     36     int x,y,v,cnt,fg;     ///fg状态压缩表示当前吃了哪些金币
     37     void ini(){           ///v代表当前有多少金币,cnt代表走了几步
     38         v=cnt=fg=0;
     39     }
     40 }node,temp;
     41 void bfs(){
     42     queue<Node>q;
     43     q.push(node);
     44     while(!q.empty()){
     45         node=q.front();q.pop();
     46         int x=node.x;int y=node.y;
     47         if(x==tx&&y==ty){
     48             if(node.v>=k){
     49                 printf("%d
    ",node.cnt);
     50                 return;
     51             }
     52             continue;
     53         }
     54         temp=node;
     55         if(pic[x][y]=='P'&&temp.v){    ///走到了有传送门的位置
     56             temp.cnt++;                ///并且有路费可以用传送门
     57             temp.v--;
     58             for(int i=0;i<dcnt;++i){
     59                 if((dx[i]==x&&dy[i]==y))continue;
     60                 int xx=dx[i],yy=dy[i];
     61                 if(vis[xx][yy][temp.fg][temp.v])continue;
     62                 vis[xx][yy][temp.fg][temp.v]=1;
     63                 temp.x=xx;temp.y=yy;
     64                 q.push(temp);
     65             }
     66         }
     67         for(int i=0;i<4;++i){
     68             temp=node;
     69             temp.cnt++;
     70             int xx=x+dir[i][0],yy=y+dir[i][1];
     71             if(xx<1||xx>n||yy<1||yy>m||pic[xx][yy]=='#')continue;
     72             if(isdigit(pic[xx][yy])){   ///走到了有金币的位置
     73                 if(temp.fg&(1<<(pic[xx][yy]-'0'))){  ///金币已经吃过了
     74                     if(!vis[xx][yy][temp.fg][temp.v]){
     75                         vis[xx][yy][temp.fg][temp.v]=1;
     76                         temp.x=xx;temp.y=yy;
     77                         q.push(temp);
     78                     }
     79                 }
     80                 else{        ///金币还没吃过
     81                     temp.fg|=(1<<(pic[xx][yy]-'0'));
     82                     temp.v++;
     83                     if(!vis[xx][yy][temp.fg][temp.v]){
     84                         vis[xx][yy][temp.fg][temp.v]=1;
     85                         temp.x=xx;temp.y=yy;
     86                         q.push(temp);
     87                     }
     88                 }
     89             }
     90             else{
     91                 if(!vis[xx][yy][temp.fg][temp.v]){
     92                     vis[xx][yy][temp.fg][temp.v]=1;
     93                     temp.x=xx;temp.y=yy;
     94                     q.push(temp);
     95                 }
     96             }
     97         }
     98     }
     99     printf("-1
    ");
    100 }
    101 int main(){
    102     int i,j,group,Case=0;
    103     scanf("%d",&group);
    104     while(group--){
    105         int gold=0;dcnt=0;///gold是将'C'转换为数字,方便状态压缩
    106         mst(vis,0);
    107         scanf("%d%d%d",&n,&m,&k);
    108         node.ini();
    109         for(i=1;i<=n;++i){
    110             scanf("%s",pic[i]+1);
    111             for(j=1;j<=m;++j){
    112                 if(pic[i][j]=='C') pic[i][j]='0'+gold++;
    113                 else if(pic[i][j]=='P'){
    114                     dx[dcnt]=i;dy[dcnt++]=j; 
    115                     vis[i][j][0][0]=1;
    116                 }
    117                 else if(pic[i][j]=='E'){
    118                     tx=i;ty=j;
    119                 }
    120                 else if(pic[i][j]=='S'){
    121                     node.x=i;node.y=j;
    122                 }
    123             }
    124         }
    125         bfs();
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    const 深悟理解
    深拷贝与浅拷贝深究
    结队开发-最大子数组
    软件工程个人作业02
    四则运算关于加括号的思路
    实践出真知-所谓"java没有指针",那叫做引用!
    写代码的好习惯—先构思
    团队合作
    阿超超的四则运算 想啊想啊
    Github+阿超运算
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5583701.html
Copyright © 2011-2022 走看看