• 【题解】密室逃脱


    题面描述

    即使czhou没有派出最强篮球阵容,机房篮球队还是暴虐了校篮球队。为了不打击校篮球队信心,czhou决定改变训练后的活动。近来,江大掌门的徒弟徒孙们纷纷事业有成,回到母校为机房捐钱捐物。财大气粗的机房组收回了五层六层的所有教室。Czhou决定将六层的教室改造为智能密室逃脱活动室。

    每天傍晚,神牛们可以依次逐个进入游玩。我们简单的将教室分割为n*n个房间,K是你初始所在房间,T是你最终逃脱的房间。如果你想要逃脱房间,你必须依次找到m把钥匙。我们假定你从一个房间进入另一个房间需要花费1的时间。当然某些房间有些特殊的问题(地图上S表示)需要回答才能通过,对于机智的众牛们来说,这些问题根本不是问题。我们假定众牛们花费1的时间解决问题。(主要是出题的人表述不清,导致众牛理解困难;当然问题只需要回答一次,下次再次进入房间不需要y回答了)

    Input:maze.in

    第一行两个数字n,m

    接下来n*n描述地图

    Output: maze.out

    需要最少步数逃脱密室。若无解输出impossible

    Sample1.in:

    3 1

    K.S

    1

    1#T

    Sample1.outvb

    5

    Sample2.in

    3 1

    K#T

    .S#

    1#.

    Sample2.out

    Impossible

    Sample3.in

    3 2

    K#T

    .S.

    Sample3.out

    8

    样例3说明:

    要先取钥匙1,再取钥匙2。地图上可能有多个同一种钥匙,#为墙壁即不可走.

    数据范围:

    0 < N <= 100, 0<=M<=9,S的个数<=5

    题解

    因为s走过一次就消失,并且s很小,所以特殊处理,dfs搜索选哪些S,在最后的答案中加上s的额外支出
    选这个s就将原地图中的相应位置设为'.',不选就设为'#'
    f[i][j][k]表示走到bd[i][j]这个位置,并且当前拿到了第k种钥匙时的最短路
    bfs求最短路
    代码调不出来

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<bitset>
    #include<set>
    #include<map>
    #define LL long long
    using namespace std;
    inline void Read(int &x){
    	int f=1;
    	char c=getchar();
    	x=0;
    	while(c<'0'||c>'9'){
    		if(c=='-')f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		x=(x<<3)+(x<<1)+c-'0';
    		c=getchar();
    	}
    	x*=f;
    }
    int n, m, tx, ty, ex, ey, sx[6], sy[6], cnt;
    int f[105][105][11], q[10010][4], head, tail;
    int x[5] = {0, 0, 0, 1, -1}, y[5] = {0, 1, -1, 0, 0};
    LL ans;
    int fl;
    char bd[105][105];
    void bfs(){
    	memset(f, -1, sizeof(f));
    	f[tx][ty][0] = 0;
    	q[1][1] = tx; q[1][2] = ty; q[1][3] = 0;
    	head = 1; tail = 1;
    	while(head <= tail){
    	
    		int i = q[head][1], j = q[head][2], key = q[head][3]; head++; 
    		
    //		printf(" %d %d %d %d
    ", i, j, key, f[i][j][key]);
    		for(int k = 1; k <= 4; ++k){
    			fl = 0;
    			int keynow = key;
    //			if(i + x[k] == 2 && j + y[k] == 3 && keynow == 2){
    //				fl = 1; printf("yep
    ");
    //			}
    			if(i + x[k] < 1 || i + x[k] > n || j + y[k] < 1 || j + y[k] > n){
    //				if(fl == 1)printf("died 1
    ");
    				continue;
    			}	
    			if(bd[i + x[k]][j + y[k]] == '#'){
    //				if(fl == 1)printf("died 2
    ");
    				continue;
    			}
    			if(f[i + x[k]][j + y[k]][keynow] != -1){
    //				if(fl == 1)printf("died 3
    ");
    				continue;
    			}		
    			if(bd[i + x[k]][j + y[k]] == '0' + keynow + 1){
    //				printf("*%d %d
    ", bd[i + x[k]][j +y[k]] - '0', keynow + 1);
    				keynow++;
    			}	
    			
    			f[i + x[k]][j + y[k]][keynow] = f[i][j][key] + 1;
    			q[++tail][1] = i + x[k]; q[tail][2] = j + y[k];	q[tail][3] = keynow;
    //			printf("-> %d %d %d %d
    ", i + x[k], j + y[k], keynow, f[i + x[k]][j + y[k]][keynow]);
    		}
    	}
    }
    void dfs(int pos, int chosn){
    //	printf("%d %d
    ", pos, chosn);
    	if(pos == cnt + 1){
    		bfs();
    		if(f[ex][ey][m] != -1){
    			ans = min(ans, 0ll + f[ex][ey][m] + chosn);
    			printf("ans = %lld
    ", ans);
    		}
    			
    		return ;
    	}
    	bd[sx[pos]][sy[pos]] = '.';
    	dfs(pos + 1, chosn + 1);
    	bd[sx[pos]][sy[pos]] = '#';
    	dfs(pos + 1, chosn);
    }
    int main()
    {
    	freopen("maze2.in","r",stdin);
    //	freopen("maze.out","w",stdout);
    	ans = 1000000000;
    	Read(n); Read(m);
    	for(int i = 1; i <= n; ++i){
    		for(int j = 1; j <= n; ++j){
    			cin >> bd[i][j];
    			if(bd[i][j] == 'K'){tx = i; ty = j;}
    			if(bd[i][j] == 'T'){ex = i; ey = j;}
    			if(bd[i][j] == 'S'){sx[++cnt] = i; sy[cnt] = j;}
    		}
    	}
    //	for(int i = 1; i <= n; ++i){
    //		for(int j = 1; j <= n; ++j)	cout << bd[i][j] << " ";
    //		cout << "
    ";
    //	}
    //	printf("%d %d %d %d
    ", tx, ty, ex, ey);
    	dfs(1, 0);
    	if(ans < 1000000000)
    		printf("%lld
    ", ans);
    	else printf("impossible
    ");
    	return 0;
    }
    
    
  • 相关阅读:
    mooc-IDEA 项目/文件之间跳转--002
    003--PowerDesigner创建索引与外键
    002--PowerDesigner显示注释comment
    001--PowerDesigner连接MySQL
    如果说需要注册数据中心,这样才能使用demo部署数据中心license证需要申请,使用云之间-工作流程......
    eas之如何获取当前用户
    eas之f7
    eas之打开窗体
    eas之怎么设置单据保存或者提交完不跳到下个新增页面
    eas之EntityViewInfo对象mainQuery中查询条件
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/14417246.html
Copyright © 2020-2023  润新知