2021-01-23 搜索入门

B ——Dungeon Master

You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides.

Is an escape possible? If yes, how long will it take?

Input

The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size).
L is the number of levels making up the dungeon.
R and C are the number of rows and columns making up the plan of each level.
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a ‘#’ and empty cells are represented by a ‘.’. Your starting position is indicated by ‘S’ and the exit by the letter ‘E’. There’s a single blank line after each level. Input is terminated by three zeroes for L, R and C.

Output

Each maze generates one line of output. If it is possible to reach the exit, print a line of the form
Escaped in x minute(s).

where x is replaced by the shortest time it takes to escape.
If it is not possible to escape, print the line
Trapped!

Sample Input

3 4 5
S…
.###.
.##…
###.#

##.##
##…

#.###
####E

1 3 3
S##
#E#

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!

大致题意:
有一个三维牢笼,一个人从起点S出发,要到达终点E,并且只能走“。”路,不能走“#”路。试求出能否逃脱,如能逃脱,求出最短路径。

解题方法:

#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int l,r,c;
char map[35][35][35];//存储每个坐标的内容 
int direction[6][3]={
    
    {
    
    1,0,0},{
    
    -1,0,0},{
    
    0,1,0},{
    
    0,-1,0},{
    
    0,0,1},{
    
    0,0,-1}};
int visited[35][35][35];
int dis[205][205]; 

struct node{
    
    
	int x,y,z;//记录某一位置的坐标
	int step;//从起点到该位置的距离 
};

struct node start;//起点
struct node end;//终点
struct node t; //跳出循环节点 


bool check(int x,int y,int z){
    
    
    if ((x>=0)&&(x<l)&&(y>=0)&&(y<r)&&(z>=0)&&(z<c)&&(!visited[x][y][z])&&(map[x][y][z]=='.'||map[x][y][z]=='E'))
        return true;
    else
        return false;
}


void bfs(){
    
    
	struct node next;//储存下一个节点的数据
	queue<node>q;
	q.push(start);
	while(!q.empty()){
    
    
		t=q.front();
		q.pop();
		if(t.x==end.x&&t.y==end.y&&t.z==end.z) return;//如果已经到达终点 
		else{
    
    
            visited[t.x][t.y][t.z]=1;
            for (int i=0;i<6;i++){
    
    
                next.x=t.x+direction[i][0];
                next.y=t.y+direction[i][1];
                next.z=t.z +direction[i][2];
                if (check(next.x,next.y,next.z)){
    
    
                    next.step=t.step+1;
                    visited[next.x][next.y][next.z]=1;
                    q.push(next);
                }
                
             }
        }
    }
	
}


int main(){
    
    
	while(~scanf("%d %d %d",&l,&r,&c)){
    
    
		if(l==0&&r==0&&c==0)break;
		memset(visited,0,sizeof(visited));
		for(int i=0;i<l;i++){
    
    
		   getchar();//两个getchar()。。。吐了 
		   //可以用字符串输入来避免!
		   for(int j=0;j<r;j++){
    
    
		      for(int k=0;k<c;k++){
    
    
		      	scanf("%c",&map[i][j][k]);
		      	if(map[i][j][k]=='S'){
    
    start.x=i;start.y=j;start.z=k;start.step=0;}//标记起点 
		      	if(map[i][j][k]=='E'){
    
    end.x=i;end.y=j;end.z=k;end.step=0;}//标记终点 
			  }
			  getchar();  
	     	}
    	}
	    bfs();//去搜索 
		if(t.x==end.x&&t.y==end.y&&t.z==end.z)//到终点跳出循环,代表路径能走通
		   cout<<"Escaped in " <<t.step<<" minute(s)." <<endl;
		else
		   cout<<"Trapped!"<<endl;    
	}
	return 0;
}

G ——wyh2000 and pupil

Young theoretical computer scientist wyh2000 is teaching his pupils.

Wyh2000 has n pupils.Id of them are from 1 to n.In order to increase the cohesion between pupils,wyh2000 decide to divide them into 2 groups.Each group has at least 1 pupil.

Now that some pupils don’t know each other(if a doesn’t know b,then b doesn’t know a).Wyh2000 hopes that if two pupils are in the same group,then they know each other,and the pupils of the first group must be as much as possible.

Please help wyh2000 determine the pupils of first group and second group. If there is no solution, print “Poor wyh”.

Input

In the first line, there is an integer T indicates the number of test cases.

For each case, the first line contains two integers n,m indicate the number of pupil and the number of pupils don’t konw each other.

In the next m lines,each line contains 2 intergers x,y(x<y),indicates that x don’t know y and y don’t know x,the pair (x,y) will only appear once.

T≤10,0≤n,m≤100000

Output

For each case, output the answer.

Sample Input

2
8 5
3 4
5 6
1 2
5 8
3 5
5 4
2 3
4 5
3 4
2 4

Sample Output

3 5
poor wyh!

大致题意:
有n个人,其中有m组不认识关系。要将这n个人分为两组,每组必须是彼此认识的人。最重要的是,每个组 必须 有一个人及以上!

方法:二分染色

#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;

vector<int>v[100005];//储存不认识的人 
int cnt[3];//每一边储存的人数 
int color[100005];//储存每个人被染的颜色 认识的人染相同的颜色 不认识的人染不同的颜色      

bool dfs(int x){
    
    
	for(int i=0;i<v[x].size();i++){
    
    //i代表的都是x所不认识的人 
		int k=v[x][i];
		if(color[k]==-1){
    
    //给没有染色的人染上和上一个人不同的颜色 
			color[k]=3-color[x]; 
			cnt[color[k]]++;
			if(!dfs(k))return false;//该人出发无法分成二分图 
		}
		else if(color[k]==color[x])//不认识的分在了一起 
		{
    
    
			return false;
		}
	}
	return true;    
}

int main(){
    
    
	int T;
	cin>>T;
	while(T--){
    
    
		int ans = 0;
		int m,n;
		scanf("%d %d",&m,&n);
		if(m<2){
    
    
			printf("Poor wyh\n");
			continue;
		}
		
		
		int num1,num2;
		for(int i = 0;i < n;i++){
    
    
			scanf("%d%d",&num1,&num2);
			v[num1].push_back(num2);
			v[num2].push_back(num1);//存储每个人不认识的人 
		}
		memset(color,-1,sizeof(color));
        
        bool flag=false;
		for(int i=1;i<=m;i++){
    
     
			if(color[i]==-1){
    
    //没有染色 
				color[i]=1;//任意染一个颜色 
				cnt[1]=1;//颜色1的人数 
				cnt[2]=0;//颜色2的人数 
				if(!dfs(i)){
    
    //没法形成二分图 
					printf("Poor wyh\n");
					flag=true;
					break;
				}
		     	ans+=max(cnt[1],cnt[2]);//答案就是人数更多的一组 
			}
		}
		if(flag) continue;
		if(ans==m)printf("%d %d\n",m-1,1);//每组至少要有一个人 
		else  printf("%d %d\n",ans,m-ans);
	}
	
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/m0_52433146/article/details/113047373