UVA 1601 The Morning after Halloween(搜索,二维数组转为图)

学习:

  转化成图

  1 //#include<bits/stdc++.h>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 using namespace std;
  6 typedef long long ll;
  7 int n,m,k;
  8 char maps[20][20];
  9 int vis[200][200][200];
 10 int num[20][20];
 11 int que[10000000][4];
 12 int connect[200][200];
 13 int goal[4];
 14 int all;
 15 int ans = -1;
 16 void bfs(){
 17     int front = 0 , rear = 1;
 18     while(front < rear){
 19         int a = que[front][1] , b = que[front][2] , c = que[front][3];
 20         vis[a][b][c] = true;
 21         int step = que[front][0];
 22
 23         //cout << a << " - " << goal[1] << endl;
 24         //cout << b << " - " << goal[2] << endl;
 25         //cout << c << " - " << goal[3] << endl;
 26
 27         if(a == goal[1] && b == goal[2] && c == goal[3]){
 28             ans = step;
 29             return;
 30         }
 31         // a 是图上某个点  , coonect是邻接表。
 32         for(int i = 0 ; i <= connect[a][0] ; i ++){
 33             int na = i ? connect[a][i] : a;
 34             for(int j = 0 ; j <= connect[b][0] ; j ++){
 35                 int nb = j ? connect[b][j] : b;
 36                 for(int k = 0 ; k <= connect[c][0] ; k ++){
 37                     int nc = k ? connect[c][k] : c;
 38                     if((na && nb && na == nb) ||(na && nc && na == nc)||(nb && nc && nb == nc)) continue;
 39                     if((na && nb) && na == b && nb == a) continue;
 40                     if((nb && nc) && nb == c && nc == b) continue;
 41                     if((na && nc) && na == c && nc == a) continue;
 42                     if(!vis[na][nb][nc]){
 43                         vis[na][nb][nc] = true;
 44                         que[rear][0] = step + 1;
 45                         que[rear][1] = na;
 46                         que[rear][2] = nb;
 47                         que[rear][3] = nc;
 48                         rear ++;
 49                     }
 50                 }
 51             }
 52         }
 53         front ++;
 54     }
 55 }
 56 int main(){
 57     /**
 58      *先计算有几个点,  1......n
 59      *再遍历每个点 pos(1~n), 与之相邻的 建立邻接表
 60      * 再将起点 终点映射为 图中的下标。
 61      * */
 62     while(scanf("%d%d%d",&m,&n,&k) != EOF && (n||m||k)){
 63         getchar();
 64         for(int i = 0 ; i < n ; i ++){
 65             gets(maps[i]);
 66         }
 67         all = 0;
 68         memset(connect,0,sizeof(connect));
 69         memset(num,0,sizeof(num));
 70         memset(vis,0,sizeof(vis));
 71         for(int i = 0 ; i < n ; i ++){
 72             for(int j = 0 ; j < m ; j ++){
 73                 // 图的下标从一开始
 74                 if(maps[i][j] != ‘#‘) num[i][j] = ++all;
 75             }
 76         }
 77         for(int i = 0 ; i < n ; i ++){
 78             for(int j = 0 ; j < m ; j ++){
 79                 int &pos = num[i][j];
 80                 if(num[i][j]){
 81                     // 转为邻接表, connect[pos][0] 表示有几个点和该点相连。
 82                     if(num[i-1][j]) connect[pos][++connect[pos][0]] = num[i-1][j];
 83                     if(num[i+1][j]) connect[pos][++connect[pos][0]] = num[i+1][j];
 84                     if(num[i][j-1]) connect[pos][++connect[pos][0]] = num[i][j-1];
 85                     if(num[i][j+1]) connect[pos][++connect[pos][0]] = num[i][j+1];
 86                 }
 87             }
 88         }
 89
 90         que[0][1] = que[0][2] = que[0][3] = goal[1] = goal[2] = goal[3] = 0;
 91         que[0][0] = 0;
 92         for(int i = 0 ; i < n ; i ++){
 93             for(int j = 0 ; j < m ; j ++){
 94                 if(num[i][j]){
 95                     if(maps[i][j] == ‘a‘) que[0][1] = num[i][j];
 96                     else if(maps[i][j] == ‘b‘) que[0][2] = num[i][j];
 97                     else if(maps[i][j] == ‘c‘) que[0][3] = num[i][j];
 98                     else if(maps[i][j] == ‘A‘) goal[1] = num[i][j];
 99                     else if(maps[i][j] == ‘B‘) goal[2] = num[i][j];
100                     else if(maps[i][j] == ‘C‘) goal[3] = num[i][j];
101                 }
102             }
103         }
104         bfs();
105         printf("%d\n",ans);
106     }
107     return 0;
108 }
109 /**
110 4 3 1
111 ####
112 #aA#
113 ####
114 5 5 2
115 #####
116 #A#B#
117 #   #
118 #b#a#
119 #####
120 16 4 3
121 ################
122 ## ########## ##
123 #    ABCcba    #
124 ################
125 16 16 3
126 ################
127 ### ##    #   ##
128 ##  #  ##   # c#
129 #  ## ########b#
130 # ##  # #   #  #
131 #  # ##   # # ##
132 ##  a#  # # #  #
133 ### ## #### ## #
134 ##   #   #  #  #
135 #  ##### # ## ##
136 ####   #B# #   #
137 ##  C#   #   ###
138 #  # # ####### #
139 # ######  A##  #
140 #        #    ##
141 ################
142 0 0 0
143 36
144 */
时间: 2024-10-16 11:31:28

UVA 1601 The Morning after Halloween(搜索,二维数组转为图)的相关文章

将二维数组转为一维数组的2种方法

如何将下面的二维数组转为一维数组. 代码如下: $msg = array( array( 'id'=>'45', 'name'=>'jack' ), array( 'id'=>'34', 'name'=>'mary' ), array( 'id'=>'78', 'name'=>'lili' ), ); 第一种方法: 代码如下: foreach($msg as $k => $v){ $ids[] = $id; $names[] = $name; } 第二种方法: 代

将二维数组转为稀疏数组

public class SparseArray { /** * 用二维数组实现一个棋盘,1代表黑子,2代表蓝子 */ public static void main(String[] args) { /** * 二维数组 */ int[][] chessArray1 = new int[11][11]; chessArray1[1][2] = 1; chessArray1[2][3] = 2; for (int[] row : chessArray1) { for (int data : ro

php函数array_column如何将二维数组转为一维数组

/*** * 参数1二维数组,参数2 返回一维数组的值的键值 参数3 用参数3作为返回一维数组的键值 */ $last_names = array_column($records, 'last_name', 'first_name'); print_r($last_names);

解决二维数组转为ArrayList集合问题

2015年4月9日 天气冷 起初我参考的代码如下: 修改前代码块 String[][] str = { { "语文", "100" }, { "英语", "90" }, { "数学", "90" }, }; ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < str.le

返回一个二维数组中最大联通子数组的和

1 #include <iostream> 2 #include <time.h> 3 #include<string> 4 #include<fstream> 5 #define M 3 6 #define N 4 7 using namespace std; 8 9 int main() 10 { 11 int length[100],num[M][N] = {0},visit[M][N]={0},i=0;//length[100],是把文件中的数组转化

PHP如何随机获取一个二维数组中的一个值

获取一个数组: $awardid_list=pdo_fetchall('select id from '.tablename($this->table_award)); 这是微擎的写法哈,意思就是查询一组字段为id的数据: 二维数组如图: 那么值是1.2.3,我们如何随机获取呢,请往下看代码: $no=array_rand($awardid_list); print_r($awardid_list[$no]['id']); 这样就OK了哈,就可以随机获取值1.2.3了哦.

C++基础知识——二维数组做函数参数

1.确定大小的二维数组 void Func(int array[3][10]); void Func(int array[][10]); 2.不确定大小的二维数组转为二维指针: 从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,所以可以转换成二维指针. void Func(int **array, int m, int n); 调用时候要把数组名转换位二维指针 Func((int**)a, 3, 3); 获取具体数组元素 *((int*)array + n

c语言中如何通过二级指针来操作二维数组

通过二级指针去访问二维数组需要先给二级指针分配等同于二维数组行数的一维数组指针,然后把二维数组的每行首地址赋值给对应位置的一维指针上.之后就可以通过二维指针直接访问了. 参考代码如下,可以看具体注释辅助理解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h>//输入输出头文件. #include <stdlib.h>//本程序需要用到malloc/free函数,引

二维数组转稀疏数组、稀疏数组恢复二维数组(Java实现)

public static void main(String[] args) { // 创建一个原始的二维数组 9*9 int chessArr1[][] = new int[9][9]; // 0表示没有棋子,1表示黑子,2表示白子 chessArr1[1][2] = 1; chessArr1[2][3] = 2; chessArr1[5][2] = 2; chessArr1[7][6] = 2; chessArr1[8][4] = 1; System.out.println("原始的二维数组