[kuangbin带你飞]专题一 简单搜索 题解

版权声明:点个关注(^-^)V https://blog.csdn.net/weixin_41793113/article/details/87725725

专题一 简单搜索 

poj1321 感觉这题是八皇后的变形,一开始无脑搜索,对于每次每个点的n^2搜索,超时了,后来像八皇后那样,对每次每行搜索,这样每次都是n的复杂度的搜索了,而且还是逐层递增的往下搜索,所以也并不是到n,也不会有n^2那样的有t!阶乘的答案出现,好啦,bb多了

import java.util.Scanner;

public class poj1321 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			n = in.nextInt();
			k = in.nextInt();
			if(n==-1 && k==-1)
				break;
			ans = 0;
			ch = new char[n][n];
			c = new boolean[n];
			for(int i=0;i<n;i++)
				ch[i] = in.next().toCharArray();
			dfs(0,0);
			System.out.println(ans);
		}
	}
	
	static int n,k;
	static long ans = 0;
	static char[][] ch;
	static boolean[] c;
	
	static void dfs(int i,int m) {
		if(m>=k) {
			ans++;
			return;
		}
		if(i>=n)
			return;
		for (int j = 0; j < n; j++)
			if (ch[i][j] == '#' && !c[j]) {
				c[j] = true;
				dfs(i + 1,m+1);
				c[j] = false;
			}
		dfs(i + 1,m);
	
	}
}

poj2251 这题一模一样的java代码,内存溢出了,对java很不友善呐

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;

char map[35][35][35];
int vis[35][35][35];
int k,n,m,sx,sy,sz,ex,ey,ez;
int to[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};//上下东西南北

struct node
{
    int x,y,z,step;
};

int check(int x,int y,int z)//检查是否可走
{
    if(x<0 || y<0 || z<0 || x>=k || y>=n || z>=m)//越界判断
        return 1;
    else if(map[x][y][z] == '#')
        return 1;
    else if(vis[x][y][z])
        return 1;
    return 0;
}

int bfs()
{
    node u,v;
    queue<node> Q;
    u.x = sx,u.y = sy,u.z = sz;
    u.step = 0;
    vis[sx][sy][sz] = 1;
    Q.push(u);
    while(!Q.empty())
    {
        u = Q.front();
        Q.pop();
        if(u.x == ex && u.y == ey && u.z == ez)
            return u.step;
        for(int i = 0; i<6; i++)
        {
            v.x = u.x+to[i][0];
            v.y = u.y+to[i][1];
            v.z = u.z+to[i][2];
            if(check(v.x,v.y,v.z))
                continue;
            vis[v.x][v.y][v.z] = 1;
            v.step = u.step+1;
            Q.push(v);
        }
    }
    return 0;
}

int main()
{
    int i,j,r;
    while(scanf("%d%d%d",&k,&n,&m),n+m+k)
    {
        for(i = 0; i<k; i++)
        {
            for(j = 0; j<n; j++)
            {
                scanf("%s",map[i][j]);
                for(r = 0; r<m; r++)
                {
                    if(map[i][j][r] == 'S')
                    {
                        sx = i,sy = j,sz = r;
                    }
                    else if(map[i][j][r] == 'E')
                    {
                        ex = i,ey = j,ez = r;
                    }
                }
            }
        }
        memset(vis,0,sizeof(vis));
        int ans;
        ans = bfs();
        if(ans)
            printf("Escaped in %d minute(s).\n",ans);
        else
            printf("Trapped!\n");
    }

    return 0;
}

poj3278  记得标记标记标记!!!

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class poj3278 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		k = in.nextInt();
		System.out.println(bfs());
	}
	
	
	static int n,k;
	static boolean[] vis = new boolean[100005];
	
	static int bfs() {
		Queue<Node> q = new LinkedList<Node>();//poj不支持<> 要写<Node>
		q.add(new Node(n, 0));
		vis[n] = true;
		while(!q.isEmpty()) {
			Node u = q.poll();
			if(u.x == k)
				return u.t;
			if(k>u.x  && u.x+1<=100001 && !vis[u.x+1]) {
				q.add(new Node(u.x+1, u.t+1));
				vis[u.x+1] = true;
			}
			if(u.x>=0 && u.x-1>=0 && !vis[u.x-1]) {
				q.add(new Node(u.x-1, u.t+1));
				vis[u.x-1] = true;
			}
			if(k>u.x && 2*u.x<=100001 && !vis[2*u.x]) {
				q.add(new Node(2*u.x, u.t+1));
				vis[2*u.x] = true;
			}
		}
		return -1;
	}
	
	static class Node {
		int x,t;
		public Node(int x,int t) {
			this.x = x;
			this.t = t;
		}
	}
	
	
}

poj3279暂时跳过了  https://blog.csdn.net/a1097304791/article/details/82997059

扫描二维码关注公众号,回复: 5565184 查看本文章

poj1426 java的long是10位 c++的longlong是19位,java用bfs+大数类做这题内存超出,c++的bfs也超时,不过呢,c++的dfsAC了,这么神奇的么??思想也差不多,不过bfs不会剪枝,dfs找到一个解就return所有,最后我还试了下,java的大数+dfs,超时了,证明c++好很多,对java不友善,不过用数论+搜索的方式来写会好很多。网上有

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;

int flag,n;
void dfs(long long int t,int k)
{

    if(flag==1)
        return;
    if(t%n==0)
    {
        flag=1;
        cout<<t<<endl;
        return;
    }
	if(k==19)
        return;
    dfs(t*10,k+1);
    dfs(t*10+1,k+1);
    return;
}

int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        flag=0;
        dfs(1,1);
    }
    return 0;
}

poj3126 bfs 暴力到没朋友,1000-9999的素数就1000多个,把他们存在list里面,然后每次都枚举1000多个,撑死10次找不到答案就是impossble了吧

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;

public class poj3126 {

	public static void main(String[] args) {
		is[1] = true;
		for(int i=2;i<10000;i++)
			if(!is[i])
				for(int j=2*i;j<10000;j+=i)
					is[j] = true;
		for(int i=1000;i<10000;i++)
			if(!is[i])
				list.add(i);
		Scanner in = new Scanner(System.in);
		int T = in.nextInt();
		while(T-->0) {
			for(int i=0;i<10000;i++)
				vis[i] = false;
			int ans = bfs(in.nextInt(),in.nextInt());
			if(ans==-1)
				System.out.println("Impossible");
			else
				System.out.println(ans);			
		}

	}
	
	static boolean is[] = new boolean[10000];
	static boolean vis[] = new boolean[10000];
	static List<Integer> list = new ArrayList<Integer>();

	static class Node implements Comparable<Node>{
		int x,k;
		public Node(int x,int k) {
			this.x = x;
			this.k = k;
		}
		@Override
		public int compareTo(Node o) {
			return this.k - o.k;
		}
		
	}
	
	static int bfs(int x,int y) {
		Queue<Node> q = new LinkedList<Node>();
		q.add(new Node(x,0));
		vis[x] = true;
		while(!q.isEmpty()) {
			Node u = q.poll();
//			System.out.println(u.x+"   "+u.k);
			if(u.x == y)
				return u.k;
			for(int i=0;i<list.size();i++) 
				if(!is[list.get(i)] && !vis[list.get(i)] && check(""+u.x,""+list.get(i))) {
					vis[list.get(i)] = true;
					q.add(new Node(list.get(i), u.k+1));	
				}
		}
		
		return -1;
	}
	
	static boolean check(String x,String y) {
		int t=0;
		for(int i=0;i<4;i++)
			if(x.charAt(i)!=y.charAt(i))
				t++;
		return t==1;
	}
	

}

poj3414  这题和hdu 1495 非常可乐这题很像,就多了个打印路径,注意的是copy类似的if的时候改动的东西别忘记不改了,还有注意标记标记标记

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class poj3414 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		A = in.nextInt();
		B = in.nextInt();
		C = in.nextInt();
		bfs();
	}

	static int A,B,C;
	static boolean[][] vis = new boolean[105][105];
	static String[] s = new String[] {"-1","FILL(1)","DROP(1)","POUR(1,2)","FILL(2)","DROP(2)","POUR(2,1)"};

	static class Node {
		int a,b,t;
		String s;
		public Node(int a,int b,int t,String s) {
			this.a = a;
			this.b = b;
			this.t = t;
			this.s = s;
		}
	}

	static void bfs() {
		Queue<Node> q = new LinkedList<Node>();
		q.add(new Node(0, 0, 0,""));
		vis[0][0] = true;
		while(!q.isEmpty()) {//1.加满a 2.倒光a 3.a->b 4.加满b 5.倒光b 6.b->a
			Node u = q.poll();
			if(u.a==C || u.b==C) {
				System.out.println(u.t);
				for(char c:u.s.toCharArray())
					System.out.println(s[c-'0']);
				return;
			}
			if(u.a<A) {//1.
				Node v = new Node(A, u.b, u.t+1,u.s+1);
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
			if(u.a>0) {//2.
				Node v = new Node(0, u.b, u.t+1,u.s+2);
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
			if(u.a>0 && u.b<B) {//3.
				Node v;
				if(u.a > B-u.b)
					v = new Node(u.a-(B-u.b), B, u.t+1,u.s+3);
				else
					v = new Node(0, u.a+u.b, u.t+1,u.s+3);
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
			if(u.b<B) {//4.
				Node v = new Node(u.a, B, u.t+1,u.s+4);
				if(!vis[v.a][v.b]) {

					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
			if(u.b>0) {//5.
				Node v = new Node(u.a, 0, u.t+1,u.s+5);
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
			if(u.b>0 && u.a<A) {//6.
				Node v;
				if(u.b > A-u.a)
					v = new Node(A, u.b-(A-u.a), u.t+1,u.s+6);
				else
					v = new Node(u.a+u.b, 0, u.t+1,u.s+6);
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
			}
			
		}
		
		System.out.println("impossible");
	}
	
	
}

fzu2150 WA了20次,很无奈,感觉和别人写的差不多,最后才AC,我觉得是判断最后有没全点燃出了问题吧,所以最后的java代码也过了,唉

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;

#define inf 0x3f3f3f3f

char ch[15][15];
bool vis[15][15];
int T,n,m,all=0,ans=inf;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};



struct node
{
    int x,y,t;
};

queue<node> q;
vector<node> V;
node u,v;


bool ok(int x,int y){//检查是否可走
	return x>=0 && x<n && y>=0 && y<m && !vis[x][y] && ch[x][y]=='#';
}

void init(){
	memset(vis,false,sizeof vis);
	while(!q.empty())
		q.pop();	
}

bool check(){
	for(int i=0;i<n;i++) 
		for(int j=0;j<m;j++)
			if(ch[i][j]=='#' && !vis[i][j])
				return false;
	return true;
}

int bfs(){
	int sum=0,t=0;
	while(!q.empty()){
		u = q.front();
		q.pop();
		t = u.t;
		sum++;
		
		for(int i=0;i<4;i++)
			if(ok(u.x+dx[i],u.y+dy[i])){
				vis[u.x+dx[i]][u.y+dy[i]] = true;
				v.x = u.x+dx[i];
				v.y = u.y+dy[i];
				v.t = u.t+1;
				q.push(v);
			}
	}
	return t;
}

int main(){
	
	scanf("%d",&T);
	for(int k=1;k<=T;k++){
			ans = inf;
			V.clear(); 
			scanf("%d%d",&n,&m);
			for(int i=0;i<n;i++)
				scanf("%s",&ch[i]);
			
			for(int i=0;i<n;i++) 
				for(int j=0;j<m;j++)
					if(ch[i][j]=='#') {
						u.x = i;
						u.y = j;
						u.t = 0;
						V.push_back(u);
					}
					
			for(int i=0;i<V.size();i++) 
				for(int j=i;j<V.size();j++) 
				{
					init();
					q.push(V[i]);
					q.push(V[j]);
					vis[V[i].x][V[i].y] = true;
					vis[V[j].x][V[j].y] = true;
					int tmp = bfs();
					if(check())
						ans = min(ans,tmp);
				}
							
					
      	printf("Case %d: ",k);
        if (ans==inf)
       		printf("-1\n");
        else
        	printf("%d\n",ans);
	}
	
	return 0;
}

uva11624 用java做过的题,可以用c++重做一次了,因为java又超时了。两次BFS,首先把开始的F(火)入队,然后进行BFS 并用times数组记录到达每个位置的时间(初始化为INF,不可达则为INF),然后进行逃跑路线的BFS,当满足基本条件(不越界,未被访问),再满足到达某点时间小于该点的times,则说明在火到达之前,到此位置。如此进行,知道到达边界或者队列为空也没到达(IMPOSSIBLE);一开始的想法是很暴力的,每遇到一个火就bfs一次,复杂度很高,缺不知道把所有的火放进去,然后只需要一次bfs,再加人的一次bfs即可

#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1005;
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int n,m;
int st_x,st_y;
bool vis[N][N];
int times[N][N];
int step[N][N];
char ch[N][N];
struct P{
    int x,y,s;
    P(){}
    P(int px,int py,int ps):x(px),y(py),s(ps){}
};
queue<P> q;
 
 
bool check(int x, int y){
    return x>=0 && x<n && y>=0 && y<m && !vis[x][y] && ch[x][y]!='#';
}
 
 
void clear_q(){
    while(!q.empty())
        q.pop();
}
 
void bfs_fire(){
    while(!q.empty()){
        P cur = q.front();
        q.pop();
        for(int i = 0; i < 4; ++i){
            int nx = cur.x + dir[i][0];
            int ny = cur.y + dir[i][1];
            if(check(nx,ny)){
                vis[nx][ny] = true;
                times[nx][ny] = times[cur.x][cur.y] + 1;
                q.push(P(nx,ny,times[nx][ny]));
            }
        }
    }
}
 
int bfs(int x, int y){
    step[x][y] = 0;
    q.push(P(x,y,0));
    vis[x][y] = true;
    while(!q.empty()){
        P cur = q.front();
        q.pop();
        if(cur.x == 0 || cur.x == n-1 || cur.y == 0 || cur.y == m-1){
            return step[cur.x][cur.y] + 1;
        }
        for(int i = 0; i < 4; ++i){
            int nx = cur.x + dir[i][0];
            int ny = cur.y + dir[i][1];
            if(check(nx,ny) && step[cur.x][cur.y] + 1 < times[nx][ny]){
                step[nx][ny] = step[cur.x][cur.y] + 1;
                vis[nx][ny] = true;
                q.push(P(nx,ny,step[nx][ny]));
            }
        }
    }
    return -1;
}
 
int main()
{
        ios::sync_with_stdio(false);//取消同步,反正就是输入快了 
        int t;
        cin >> t;
        while(t--){
            cin >> n >> m;
            memset(times,INF,sizeof(times));
            memset(vis,false,sizeof(vis));
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    cin >> ch[i][j];
                    if(ch[i][j] == 'J'){
                        st_x = i;
                        st_y = j;
                    }
                    if(ch[i][j] == 'F'){
                        vis[i][j] = true;
                        times[i][j] = 0;
                        q.push(P(i,j,0));
                    }
                }
            }
            bfs_fire();
            
            clear_q();//清空队列 
            memset(vis,false,sizeof(vis));//初始化 
            
            int ans = bfs(st_x,st_y);
            if(ans == -1){
                cout << "IMPOSSIBLE" <<endl;
            }
            else{
                cout << ans << endl;
            }
        }
 
 
        return 0;
}

poj3984

import java.util.Scanner;
import java.util.Stack;

//迷宫问题
public class poj3984 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		for(int i=0;i<5;i++)
			for(int j=0;j<5;j++)
				maze[i][j] = in.nextInt();
		dis.push(new Node(0, 0));
		vis[0][0] = true;
		dfs(0,0);
		

	}
	
	static int n=5;
	static int[][] maze = new int[5][5];
	static boolean[][] vis = new boolean[5][5];
	static int[] dx = new int[] {1,0,-1,0};
	static int[] dy = new int[] {0,1,0,-1};
	static Stack<Node> dis = new Stack<Node>();
	static Stack<Node> ans = new Stack<Node>();

	static void dfs(int x,int y) {
		if(x==4 && y==4) {
			while(!dis.isEmpty())
				ans.push(dis.pop());
			while(!ans.isEmpty()) {
				Node p = ans.pop();
				System.out.println("("+p.x+", "+p.y+")");
			}
			return;
		}
		for(int i=0;i<4;i++)
			if(x+dx[i]>=0 && x+dx[i]<5 && y+dy[i]>=0 && y+dy[i]<5 && maze[x+dx[i]][y+dy[i]]==0 && !vis[x+dx[i]][y+dy[i]]) {
				dis.push(new Node(x+dx[i], y+dy[i]));
				vis[x+dx[i]][y+dy[i]] = true;
				dfs(x+dx[i],y+dy[i]);
				vis[x+dx[i]][y+dy[i]] = false;
				if(dis.isEmpty())//还是因为java的公用机制,不过这样也可以在找到答案后提早退出
					return;
				dis.pop();
			}
	}
	
	static class Node{
		int x,y;
		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
}

hdu1241

import java.util.Scanner;

public class hdu1241 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			n = in.nextInt();
			if(n==0)
				break;
			m = in.nextInt();
			ch = new char[n][m];
			vis = new int[n][m];
			for(int i=0;i<n;i++)
				ch[i] = in.next().toCharArray();
			int t=0;
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
					if(ch[i][j]=='@' && vis[i][j]==0)
						dfs(++t,i,j);
			System.out.println(t);
		}
	}
	
	static int n,m;
	static int[][] vis;
	static char[][] ch;

	static int[] dx = new int[] {1,1,1,0,0,-1,-1,-1};
	static int[] dy = new int[] {0,-1,1,1,-1,1,0,-1};
	
	static void dfs(int t,int x,int y) {
		vis[x][y] = t;
		
		for(int i=0;i<8;i++) 
			if(x+dx[i]>=0 && x+dx[i]<n && y+dy[i]>=0 && y+dy[i]<m && ch[x+dx[i]][y+dy[i]]=='@' && vis[x+dx[i]][y+dy[i]]==0)
				dfs(t,x+dx[i],y+dy[i]);
		
	}

}

hdu1495

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class hdu1495 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			s = in.nextInt();
			a = in.nextInt();
			b = in.nextInt();
			if(s==0 && a==0 && b==0)
				break;
			if(b>a) {//让a是a,b里面最大的,方便判断,不过我觉得这里是累赘
				int temp = a;
				a = b;
				b = temp;
			}
			vis = new boolean[a+1][b+1];//0~n有n个状态,所以起码开n+1个空间
			int ans = bfs();
			if(ans==-1)
				System.out.println("NO");
			else
				System.out.println(ans);
		}
		
	}
	
	static int s,a,b;//代表的是最大容量,并不是此时水的容量
	static boolean[][] vis;//二维可以表示三维,用java记得初始化全局数组
	
	static class Node {
		int s,a,b,t;
		public Node(int s,int a,int b,int t) {
			this.s = s;
			this.a = a;
			this.b = b;
			this.t = t;
		}
	}
	
	static int bfs() {
		if(s%2==1)//奇数不可能平分
			return -1;
		
		Node node = new Node(s, 0, 0, 0);//初始状态
		
		Queue<Node> q = new LinkedList<>();
		vis[node.a][node.b] = true;
		q.add(node);
		while(!q.isEmpty()) {
			Node u = q.poll();
			
			if(u.s==s/2 && u.a ==s/2)
				return u.t;//终止条件
			
			//列举6个状态 s->a, s->b, a->s, a->b, b->s, b->a
			
			//放在这就是一个,会被共用,java的new的公用机制太恶心了
//			Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
			
			//s->a
			if(u.s!=0 && u.a!=a) {//不为空就可以倒水,同时接水的不能为满
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.s > a - u.a) {//如果s里面的水大于a还能装的情况
					v.s = u.s - (a - u.a);
					v.a = a;
					v.b = u.b;
				}else {//就是能完全装的下的情况了
					v.s = 0;
					v.a = u.s + u.a;
					v.b = u.b;
				}
//				System.out.println(v.a+" "+v.b);//debug用的
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
				
			}
			
			//s->b 同理
			if(u.s!=0 && u.b!=b) {
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.s > b - u.b) {
					v.s = u.s - (b - u.b);
					v.b = b;
					v.a = u.a;
				}else {
					v.s = 0;
					v.b = u.s + u.b;
					v.a = u.a;
				}
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
				
			}

			//a->s 同理
			if(u.a!=0 && u.s!=s) {
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.a > s - u.s) {
					v.a = u.a - (s - u.s);
					v.s = s;
					v.b = u.b;
				}else {
					v.a = 0;
					v.s = u.a + u.s;
					v.b = u.b;
				}
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
				
			}
			
			//a->b 同理
			if(u.a!=0 && u.b!=b) {
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.a > b - u.b) {
					v.a = u.a - (b - u.b);
					v.b = b;
					v.s = u.s;
				}else {
					v.a = 0;
					v.b = u.a + u.b;
					v.s = u.s;
				}
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}
				
			}		
			
			//b->s 同理
			if(u.b!=0 && u.s!=s) {
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.b > s - u.s) {
					v.b = u.b - (s - u.s);
					v.s = s;
					v.a = u.a;
				}else {
					v.b = 0;
					v.s = u.b + u.s;
					v.a = u.a;
				}
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}

			}
			
			//b->a 同理
			if(u.b!=0 && u.a!=a) {
				Node v = new Node(-1, -1, -1, u.t+1);//下一状态 -1表达还没初始化
				if(u.b > a - u.a) {
					v.b = u.b - (a - u.a);
					v.a = a;
					v.s = u.s;
				}else {
					v.b = 0;
					v.a = u.b + u.a;
					v.s = u.s;
				}
				if(!vis[v.a][v.b]) {
					vis[v.a][v.b] = true;
					q.add(v);
				}

			}
			
		}
		return -1;
	}

}

hdu2612

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class hdu2612 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			n = in.nextInt();
			m = in.nextInt();
			int x1 = 0,y1 = 0,x2 = 0,y2 = 0,ans = Integer.MAX_VALUE-5;
			ch = new char[n][m];
			vis = new boolean[n][m];
			dis = new int[2][n][m];
			
			for(int i=0;i<n;i++)
				ch[i] = in.next().toCharArray();
			
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
					if(ch[i][j]=='Y') {
						x1 = i;
						y1 = j;
					} else if(ch[i][j]=='M') {
						x2 = i;
						y2 = j;						
					}
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++) {
					dis[0][i][j]=1000000;//吃到苦头了,不初始步长INF一直WA,原因是KFC可能被几个#包围,org
					dis[1][i][j]=1000000;
				}
					
			bfs(0,x1,y1);
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
					vis[i][j] = false;			
			bfs(1,x2,y2);
//			for(int i=0;i<n;i++) {
//				for(int j=0;j<m;j++) {
//					System.out.print(dis[0][i][j]+dis[1][i][j]+" ");
//				}
//				System.out.println();
//			}
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
					if(ch[i][j]=='@' && dis[0][i][j]+dis[1][i][j]<ans)
						ans = dis[0][i][j]+dis[1][i][j];
			System.out.println(ans);
			
		}
	}
	
	static int n,m;
	static boolean[][] vis;
	static int[][][] dis;
	static char[][] ch;
	static int[] dx = new int[] {1,0,-1,0};
	static int[] dy = new int[] {0,1,0,-1};

	static void bfs(int who,int x,int y) {	
		Node node = new Node(x, y, 0);
		vis[x][y] = true;
		Queue<Node> q = new LinkedList<>();
		q.add(node);
		
		while(!q.isEmpty()) {
			Node u = q.poll();
			dis[who][u.x][u.y] = u.t;
			for(int i=0;i<4;i++)
				if(u.x+dx[i]>=0 && u.x+dx[i]<n && u.y+dy[i]>=0 && u.y+dy[i]<m && ch[u.x+dx[i]][u.y+dy[i]]!='#' && !vis[u.x+dx[i]][u.y+dy[i]]) {
					q.add(new Node(u.x+dx[i], u.y+dy[i], u.t+11));
					vis[u.x+dx[i]][u.y+dy[i]] = true;
				}
		}
		
	}
	
	static class Node {
		int x,y,t;
		public Node(int x,int y,int t) {
			this.x = x;
			this.y = y;
			this.t = t;
		}
	}
	
}

猜你喜欢

转载自blog.csdn.net/weixin_41793113/article/details/87725725