• 专题一、简单搜索


    很久以前刷完了Virtual Judge上的简单搜索专题,现总结如下:

    POJ 1321

    由于题目的数据范围比较小,可以直接dfs暴力。读入时记录每个空位的位置,保存在pX[]以及pY[]数组中。暴力的时候统计当前处理第几个空格以及当前处理到了第几行即可。

    #include <iostream>
    #include <memory.h>
    
    using namespace std;
    
    const int MAX = 128;
    
    
    long long ans;
    int N, K, nCnt;
    bool pUsed[MAX];
    int pX[MAX], pY[MAX];
    int pRow[MAX], pCol[MAX];
    
    void dfs(int x, int y);
    
    int main()
    {
    	char dwTmp;
    	while(cin >> N >> K)
    	{
    		if(N == -1 && K == -1) { break; }
    		nCnt = 0; ans = 0;
    		for(int i = 1; i <= N; i++)
    		{
    			for(int j = 1; j <= N; j++)
    			{
    				cin >> dwTmp;
    				if(dwTmp == '#')
    				{ nCnt++; pX[nCnt] = i; pY[nCnt] = j; }
    			}
    			cin.ignore();
    		}
    		memset(pRow, 0, sizeof(pRow));
    		memset(pCol, 0, sizeof(pCol));
    		memset(pUsed, false, sizeof(pUsed));
    		dfs(1, 0);
    		cout << ans << endl;
    	}
    	return 0;
    }
    
    void dfs(int x, int y)
    {
    	if(y == K)
    	{ ans++; }
    	else
    	{
    		for(int i = x; i <= nCnt; i++)
    		{
    			if(!(pUsed[i] || pRow[pX[i]] || pCol[pY[i]]))
    			{
    				pRow[pX[i]]++; pCol[pY[i]]++;
    				pUsed[i] = true;
    				dfs(i + 1, y + 1);
    				pUsed[i] = false;
    				pRow[pX[i]]--; pCol[pY[i]]--;
    			}
    		}
    	}
    }
    

      

    POJ 2251

    这是一个三维迷宫,对立体空间的六个方向进行bfs即可。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 32;
    
    const int dx[] = { 1, -1, 0, 0, 0, 0 };
    const int dy[] = { 0, 0, 1, -1, 0, 0 };
    const int dz[] = { 0, 0, 0, 0, 1, -1 };
    
    struct Point
    {
    	Point(int _x = 0, int _y = 0, int _z = 0, int _ans = 0)
    	{ x = _x; y = _y; z = _z; ans = 0; }
    	
    	int x, y, z, ans;
    };
    
    queue<Point> Q;
    Point Start, End;
    int pMaze[MAX][MAX][MAX];
    bool pVisited[MAX][MAX][MAX];
    
    int main()
    {
    	int L, R, C;
    	string strTmp;
    	while(cin >> L >> R >> C)
    	{
    		if(L == 0 && R == 0 && C == 0) { break; }
    		while(!Q.empty()) { Q.pop(); }
    		for(int i = 1; i <= L; i++)
    		{
    			for(int j = 1; j <= R; j++)
    			{
    				cin >> strTmp;
    				for(int k = 1; k <= C; k++)
    				{
    					if(strTmp[k - 1] == 'S') { pMaze[i][j][k] = 0; Start = Point(i, j, k); }
    					else if(strTmp[k - 1] == 'E') { pMaze[i][j][k] = 0; End = Point(i, j, k); }
    					else if(strTmp[k - 1] == '.') { pMaze[i][j][k] = 0; }
    					else if(strTmp[k - 1] == '#') { pMaze[i][j][k] = 1; }
    				}
    			}
    		}
    		Q.push(Start);
    		bool bFlag = false;
    		memset(pVisited, false, sizeof(pVisited));
    		pVisited[Start.x][Start.y][Start.z] = true;
    		while(!Q.empty())
    		{
    			Point Now = Q.front(); Q.pop();
    			if(Now.x == End.x && Now.y == End.y && Now.z == End.z) { cout << "Escaped in " << Now.ans << " minute(s)." << endl; bFlag = true; break; }
    			for(int i = 0; i < 6; i++)
    			{
    				Point Next;
    				Next.x = Now.x + dx[i]; Next.y = Now.y + dy[i]; Next.z = Now.z + dz[i]; Next.ans = Now.ans + 1;
    				if(Next.x >= 1 && Next.x <= L && Next.y >= 1 && Next.y <= R && Next.z >= 1 && Next.z <= C &&
    					pMaze[Next.x][Next.y][Next.z] == 0 && !pVisited[Next.x][Next.y][Next.z])
    				{
    					pVisited[Next.x][Next.y][Next.z] = true;
    					Q.push(Next);
    				}
    			}
    		}
    		if(!bFlag) { cout << "Trapped!" << endl; }
    	}
    	return 0;
    }
    

      

    POJ 3278

    同样是bfs,一共三种状态进行转移。

    #include <iostream>
    #include <memory.h>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 1024000;
    
    struct Pos
    {
    	Pos(int _x = 0, int _ans = 0)
    	{ x = _x; ans = _ans; }
    	
    	int x, ans;
    };
    
    queue<Pos> Q;
    bool pVisited[MAX];
    
    int main()
    {
    	int N, K;
    	while(cin >> N >> K)
    	{
    		memset(pVisited, false, sizeof(pVisited));
    		while(!Q.empty()) { Q.pop(); }
    		Q.push(Pos(N, 0)); pVisited[N] = true;
    		while(!Q.empty())
    		{
    			Pos Now = Q.front(); Q.pop();
    			if(Now.x == K) { cout << Now.ans << endl; break; }
    			if(Now.x * 2 >= 0 && Now.x * 2 < MAX && !pVisited[Now.x * 2])
    			{
    				Q.push(Pos(Now.x * 2, Now.ans + 1));
    				pVisited[Now.x * 2] = true;
    			}
    			if(Now.x - 1 >= 0 && Now.x - 1 < MAX && !pVisited[Now.x - 1])
    			{
    				Q.push(Pos(Now.x - 1, Now.ans + 1));
    				pVisited[Now.x - 1] = true;
    			}
    			if(Now.x + 1 >= 0 && Now.x + 1 < MAX && !pVisited[Now.x + 1])
    			{
    				Q.push(Pos(Now.x + 1, Now.ans + 1));
    				pVisited[Now.x + 1] = true;
    			}
    		}
    	}
    	return 0;
    }
    

      

    POJ 3279

    考虑到第一行的状态确定以后,后面的N - 1行的状态就确定了,因此只需要枚举第一行,由于数据范围比较小,所以使用二进制状态压缩即可。

    #include <iostream>
    #include <memory.h>
    
    using namespace std;
    
    const int MAX = 32;
    
    const int dx[] = { 1, -1, 0, 0 };
    const int dy[] = { 0, 0, 1, -1 };
    
    int M, N;
    int pMap[MAX][MAX];
    int pAns[MAX][MAX], pTmp[MAX][MAX];
    
    int Solve();
    int IsFlip(int x, int y);
    
    int main()
    {
    	while(cin >> M >> N)
    	{
    		int ans = 2147483647;
    		for(int i = 1; i <= M; i++)
    		{
    			for(int j = 1; j <= N; j++)
    			{ cin >> pMap[i][j]; }
    		}
    		for(int i = 0; i < (1 << N); i++)
    		{
    			memset(pTmp, 0, sizeof(pTmp));
       			for(int j = 1; j <= N; j++)
       			{
       				if(i & (1 << j - 1))
       				{ pTmp[1][j] = 1; }
       			}
       			int nTmp = Solve();
       			if(nTmp == -1) { continue; }
    			if(nTmp < ans)
    			{
    				ans = nTmp;
    				memcpy(pAns, pTmp, sizeof(pTmp));
    			}
    		}
    		if(ans != 2147483647)
    		{
    			for(int i = 1; i <= M; i++)
    			{
    				for(int j = 1; j <= N; j++)
    				{
    					cout << pAns[i][j];
    					if(j != N) { cout << " "; }
    				}
    				cout << endl;
    			}
    		}
    		else { cout << "IMPOSSIBLE" << endl; }
    	}
    	return 0;
    }
    
    int Solve()
    {
    	int nRet = 0;
    	for(int i = 2; i <= M; i++)
    	{
    		for(int j = 1; j <= N; j++)
    		{
    			if(IsFlip(i - 1, j)) { pTmp[i][j] = 1; }
    		}
    	}
    	for(int i = 1; i <= N; i++)
    	{
    		if(IsFlip(M, i)) { return -1; }
    	}
    	for(int i = 1; i <= M; i++)
    	{
    		for(int j = 1; j <= N; j++)
    		{
    			nRet += pTmp[i][j];
    		}
    	}
    	return nRet;
    }
    
    int IsFlip(int x, int y)
    {
    	int nRet = pTmp[x][y];
    	for(int i = 0; i < 4; i++)
    	{
    		int nx = x + dx[i];
    		int ny = y + dy[i];
    		if(nx >= 1 && nx <= M && ny >= 1 && ny <= N)
    		{ nRet += pTmp[nx][ny]; }
    	}
    	nRet += pMap[x][y];
    	return nRet & 1;
    }
    

      

    POJ 1426

    这道题目也是一道bfs,只需要记录每次遍历到的结果tmp % N,同时保存已选取的数字的内容,最后判断已选取的数字的长度是否符合题目的要求。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 256;
    
    const int d[] = { 0, 1 };
    
    struct Num
    {
    	Num(int _nNum = 1, string _ans = "1")
    	{
    		nNum = _nNum;
    		ans = _ans;
    	}
    
    	int nNum;
    	string ans;
    };
    
    int N;
    bool pVisited[MAX];
    queue<Num> Q;
    
    int main()
    {
    	while(cin >> N)
    	{
    		if(N == 0) { break; }
    		else
    		{
    			while(!Q.empty()) { Q.pop(); }
    			memset(pVisited, false, sizeof(pVisited));
       			Q.push(Num(1)); pVisited[1 % N] = true;
       			while(!Q.empty())
       			{
       				Num Now = Q.front(); Q.pop();
    				if(Now.nNum % N == 0) { cout << Now.ans << endl; break; }
    				for(int i = 0; i < 2; i++)
       				{
       					Num Next = Now;
    					if(!pVisited[(Now.nNum * 10 + d[i]) % N])
    					{
    						pVisited[(Now.nNum * 10 + d[i]) % N] = true;
    						Q.push(Num((Now.nNum * 10 + d[i]) % N, Now.ans + (char)(d[i] + '0')));
    					}
       				}
       			}
    		}
    	}
    	return 0;
    }
    

      

    POJ 3126

    bfs水题。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    #include <set>
    
    using namespace std;
    
    const int MAX = 10240;
    
    struct Prime
    {
    	Prime(int _x = 0, int _ans = 0)
    	{ x = _x; ans = _ans; }
    	
    	int x, ans;
    };
    
    set<int> S;
    queue<Prime> Q;
    bool pVisited[MAX];
    
    int Change(int x, int y, int z);
    
    int main()
    {
    	for(int i = 1000; i <= 9999; i++)
    	{
    		bool bFlag = true;
    		for(int j = 2; j * j <= i; j++)
    		{
    			if(i % j == 0) { bFlag = false; }
    		}
    		if(bFlag) { S.insert(i); }
    	}
    	int N, s, e;
    	while(cin >> N)
    	{
    		for(int i = 1; i <= N; i++)
    		{
    			while(!Q.empty()) { Q.pop(); }
    			memset(pVisited, false, sizeof(pVisited));
    			cin >> s >> e;
    			Q.push(Prime(s, 0)); pVisited[s] = true;
    			while(!Q.empty())
    			{
    				Prime Now = Q.front(); Q.pop();
    				if(Now.x == e) { cout << Now.ans << endl; break; }
    				for(int i = 0; i < 4; i++)
    				{
    					for(int j = 0; j <= 9; j++)
    					{
    						int nNext = Change(Now.x, i, j);
    						if(S.count(nNext) && !pVisited[nNext])
    						{
    							Q.push(Prime(nNext, Now.ans + 1));
    							pVisited[nNext] = true;
    						}
    					}
       				}
    			}
    		}
    	}
    	return 0;
    }
    
    int Change(int x, int y, int z)
    {
    	int nTmp = 1;
    	while(y--) { nTmp *= 10; }
    	x -= x / nTmp % 10 * nTmp;
    	x += z * nTmp;
    	return x;
    }
    

      

    POJ 3087

    模拟整个过程即可,如果出现与初始情况相同的情形,就说明无解。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	int N, C;
    	bool bFlag;
    	string SA, SB, S, Init;
    	cin >> N;
    	for(int i = 1; i <= N; i++)
    	{
    		cin >> C >> SA >> SB >> S;
    		int nCnt = 0; Init = ""; bFlag = false;
     		while(1)
    		{
    			nCnt++;
    			string ans = "";
    			for(int j = 0; j < SA.size(); j++)
    			{
    				ans += SB[j];
    				ans += SA[j];
    			}
    			if(Init == "") { Init = ans; }
    			SA = ans.substr(0, C);
    			SB = ans.substr(C, C);
    			if(nCnt != 1 && ans == Init) { break; }
    			if(ans == S) { cout << i << " " << nCnt << endl; bFlag = true; break; }
    		}
    		if(!bFlag) { cout << i << " -1" << endl; }
    	}
    	return 0;
    }
    

      

    POJ 3414

    bfs水题。处理好倒水的过程即可。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 128;
    
    struct Pots
    {
    	Pots(int _A = 0, int _B = 0)
    	{
    		A = _A; B = _B;
    		while(!pOpt.empty()) { pOpt.pop(); }
    	}
    	
    	int A, B;
    	queue<string> pOpt;
    };
    
    int A, B, C;
    bool pVisited[MAX][MAX];
    queue<Pots> Q;
    
    Pots Opt(Pots Now, int k);
    Pots Fill(Pots Now, int x);
    Pots Drop(Pots Now, int x);
    Pots Pour(Pots Now, int x);
    
    int main()
    {
    	bool bFlag;
    	while(cin >> A >> B >> C)
    	{
    		bFlag = false;
    		while(!Q.empty()) { Q.empty(); }
    		memset(pVisited, false, sizeof(pVisited));
    		Q.push(Pots(0, 0)); pVisited[0][0] = true;
    		while(!Q.empty())
    		{
    			Pots Now = Q.front(); Q.pop();
    			if(Now.A == C || Now.B == C)
    			{
    				cout << Now.pOpt.size() << endl;
    				while(!Now.pOpt.empty())
    				{
    					cout << Now.pOpt.front() << endl;
    					Now.pOpt.pop();
    				}
    				bFlag = true;
    				break;
    			}
    			for(int i = 0; i < 6; i++)
    			{
    				Pots Next = Opt(Now, i);
    				if(!pVisited[Next.A][Next.B])
    				{
    					Q.push(Next);
    					pVisited[Next.A][Next.B] = true;
    				}
    			}
    		}
    		if(!bFlag) { cout << "impossible" << endl; }
    	}
    	return 0;
    }
    
    Pots Opt(Pots Now, int k)
    {
    	switch(k)
    	{
    		case 0:
    			return Fill(Now, 0);
    		case 1:
    			return Fill(Now, 1);
    		case 2:
    			return Drop(Now, 0);
    		case 3:
    			return Drop(Now, 1);
    		case 4:
    			return Pour(Now, 0);
    		case 5:
    			return Pour(Now, 1);
    	}
    }
    
    Pots Fill(Pots Now, int x)
    {
    	if(x == 0) { Now.A = A; Now.pOpt.push("FILL(1)"); }
    	else { Now.B = B; Now.pOpt.push("FILL(2)"); }
    	return Now;
    }
    
    Pots Drop(Pots Now, int x)
    {
    	if(x == 0) { Now.A = 0; Now.pOpt.push("DROP(1)"); }
    	else { Now.B = 0; Now.pOpt.push("DROP(2)"); }
    	return Now;
    }
    
    Pots Pour(Pots Now, int x)
    {
    	if(x == 0)
    	{
    		Now.B += Now.A;
    		if(Now.B > B) { Now.A = Now.B - B; Now.B = B; }
    		else { Now.A = 0; }
    		Now.pOpt.push("POUR(1,2)");
    	}
    	else
    	{
    		Now.A += Now.B;
    		if(Now.A > A) { Now.B = Now.A - A; Now.A = A; }
    		else { Now.B = 0; }
    		Now.pOpt.push("POUR(2,1)");
    	}
    	return Now;
    }
    

      

    FZU 2150

    暴力枚举两个起点,然后bfs。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 16;
    
    const int dx[] = { 1, -1, 0, 0 };
    const int dy[] = { 0, 0, 1, -1 };
    
    struct Pos
    {
    	Pos(int _x, int _y, int _ans)
    	{ x = _x; y = _y; ans = _ans; }
    	
    	int x, y, ans;
    };
    
    int T, N, M;
    int pMap[MAX][MAX];
    bool pVisited[MAX][MAX];
    queue<Pos> Q;
    
    bool Check();
    int Bfs(Pos A, Pos B);
    
    int main()
    {
    	string strTmp;
    	cin >> T;
    	for(int k = 1; k <= T; k++)
    	{
    		cin >> N >> M;
    		int ans = 2147483647;
    		bool bFlag = false;
    		for(int i = 1; i <= N; i++)
    		{
    			cin >> strTmp;
    			for(int j = 1; j <= M; j++)
    			{
    				if(strTmp[j - 1] == '.') { pMap[i][j] = 1; }
    				else { pMap[i][j] = 0; }
    			}
    		}
    		for(int i = 1; i <= N; i++)
    		{
    			for(int j = 1; j <= M; j++)
    			{
    				for(int p = 1; p <= N; p++)
    				{
    					for(int q = 1; q <= M; q++)
    					{
    						if(pMap[i][j] || pMap[p][q]) { continue; }
    						int nTmp = Bfs(Pos(i, j, 0), Pos(p, q, 0));
    						if(Check()) { ans = min(ans, nTmp); bFlag = true; }
    					}
    				}
    			}
    		}
    		cout << "Case " << k << ": ";
    		if(bFlag) { cout << ans << endl; }
    		else { cout << -1 << endl; }
    	}
    	return 0;
    }
    
    int Bfs(Pos A, Pos B)
    {
    	int nRet = 0;
    	while(!Q.empty()) { Q.pop(); }
    	memset(pVisited, false, sizeof(pVisited));
    	Q.push(A); pVisited[A.x][A.y] = true;
    	Q.push(B); pVisited[B.x][B.y] = true;
    	while(!Q.empty())
    	{
    		Pos Now = Q.front(); Q.pop();
    		nRet = max(nRet, Now.ans);
    		for(int i = 0; i < 4; i++)
    		{
    			Pos Next = Now; Next.ans++;
    			Next.x += dx[i]; Next.y += dy[i];
    			if(Next.x >= 1 && Next.x <= N &&
    				Next.y >= 1 && Next.y <= M &&
    				!pVisited[Next.x][Next.y] && !pMap[Next.x][Next.y])
    			{
    				Q.push(Next);
    				pVisited[Next.x][Next.y] = true;
    			}
    		}
    	}
    	return nRet;
    }
    
    bool Check()
    {
    	for(int i = 1; i <= N; i++)
    	{
    		for(int j = 1; j <= M; j++)
    		{
    			if(!pMap[i][j] && !pVisited[i][j])
    			{ return false; }
    		}
    	}
    	return true;
    }
    

      

    UVa 11624

    注意可能有多个点起火,设定一个全局时间量,用来控制人以及火的运动顺序,先处理火,再处理人。然后就是bfs水题。

    #include <iostream>
    #include <memory.h>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 1024;
    
    const int dx[] = { 1, -1, 0, 0 };
    const int dy[] = { 0, 0, 1, -1 };
    
    struct Pos
    {
    	Pos(int _x = 0, int _y = 0, int _ans = 0)
    	{ x = _x; y = _y; ans = _ans; }
    
    	int x, y, ans;
    };
    
    int T, R, C;
    int pMap[MAX][MAX];
    bool pVJ[MAX][MAX], pVF[MAX][MAX];
    queue<Pos> J, F;
    
    int main()
    {
    	string strTmp;
    	cin >> T;
    	for(int k = 1; k <= T; k++)
    	{
    		cin >> R >> C;
    		bool bFlag = false;
    		while(!J.empty()) { J.pop(); }
    		while(!F.empty()) { F.pop(); }
    		memset(pVJ, false, sizeof(pVJ));
    		memset(pVF, false, sizeof(pVF));
    		for(int i = 1; i <= R; i++)
    		{
    			cin >> strTmp;
    			for(int j = 1; j <= C; j++)
    			{
    				if(strTmp[j - 1] == '#') { pMap[i][j] = 1; }
    				else { pMap[i][j] = 0; }
    				if(strTmp[j - 1] == 'J') { J.push(Pos(i, j)); pVJ[i][j] = true; }
    				if(strTmp[j - 1] == 'F') { F.push(Pos(i, j)); pVF[i][j] = true; }
    			}
    		}
    		int nTime = 0;
    		while(!J.empty())
    		{
    			while(!F.empty() && F.front().ans <= nTime)
    			{
    				Pos FN = F.front(); F.pop();
    				for(int i = 0; i < 4; i++)
    				{
    					Pos Next = FN; Next.ans++;
    					Next.x += dx[i]; Next.y += dy[i];
    					if(Next.x >= 1 && Next.x <= R && Next.y >= 1 && Next.y <= C &&
    						!pMap[Next.x][Next.y] && !pVF[Next.x][Next.y])
    					{
    						F.push(Next);
    						pVF[Next.x][Next.y] = true;
    					}
    				}
    			}
    			while(!J.empty() && J.front().ans  <= nTime)
    			{
    				Pos JN = J.front(); J.pop();
    				if(JN.x == 1 || JN.x == R || JN.y == 1 || JN.y == C) { cout << JN.ans + 1 << endl; bFlag = true; break; }
    				for(int i = 0; i < 4; i++)
    				{
    					Pos Next = JN; Next.ans++;
    					Next.x += dx[i]; Next.y += dy[i];
    					if(Next.x >= 1 && Next.x <= R && Next.y >= 1 && Next.y <= C &&
    						!pMap[Next.x][Next.y] && !pVF[Next.x][Next.y] && !pVJ[Next.x][Next.y])
    					{
    						J.push(Next);
    						pVJ[Next.x][Next.y] = true;
    					}
    				}
    			}
    			if(bFlag) { break; }
    			nTime++;
    		}
    		if(!bFlag) { cout << "IMPOSSIBLE" << endl; }
    	}
    	return 0;
    }
    

      

    POJ 3984

    bfs水题。

    #include <iostream>
    #include <memory.h>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 8;
    
    const int dx[] = { 1, -1, 0, 0 };
    const int dy[] = { 0, 0, 1, -1 };
    
    struct Pos
    {
    	Pos(int _x = 0, int _y = 0)
    	{ x = _x; y = _y; }
    	int x, y;
    };
    
    struct State
    {
    	State(int _x = 0, int _y = 0)
    	{
    		Now = Pos(_x, _y);
    		while(!Ans.empty()) { Ans.pop(); }
    	}
    	
    	Pos Now;
    	queue<Pos> Ans;
    };
    
    int pMap[MAX][MAX];
    bool pVisited[MAX][MAX];
    queue<State> Q;
    
    int main()
    {
    	for(int i = 1; i <= 5; i++)
    	{
    		for(int j = 1; j <= 5; j++)
    		{ cin >> pMap[i][j]; }
    	}
    	while(!Q.empty()) { Q.pop(); }
    	memset(pVisited, false, sizeof(pVisited));
    	Q.push(State(1, 1)); pVisited[1][1] = true;
    	while(!Q.empty())
    	{
    		State Now = Q.front(); Q.pop();
    		if(Now.Now.x == 5 && Now.Now.y == 5)
    		{
    			while(!Now.Ans.empty())
    			{
    				Pos Cur = Now.Ans.front();
    				cout << "(" << Cur.x - 1 << ", " << Cur.y - 1 << ")" << endl;
    				Now.Ans.pop();
    			}
    			cout << "(4, 4)" << endl;
    			break;
    		}
    		for(int i = 0; i < 4; i++)
    		{
    			int nx = Now.Now.x + dx[i];
    			int ny = Now.Now.y + dy[i];
    			if(nx >= 1 && nx <= 5 && ny >= 1 && ny <= 5 &&
    				!pVisited[nx][ny] && !pMap[nx][ny])
    			{
    				State Next = Now;
    				Next.Now = Pos(nx, ny);
    				Next.Ans.push(Now.Now);
    				Q.push(Next);
    				pVisited[nx][ny] = true;
    			}
    		}
    	}
    	return 0;
    }
    

      

    HDU 1241

    求连通块个数,直接dfs即可。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 128;
    
    const int dx[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
    const int dy[] = { 1, 1, 1, 0, 0, -1, -1, -1 };
    
    int N, M;
    int pMap[MAX][MAX];
    bool pVisited[MAX][MAX];
    
    void dfs(int x, int y);
    
    int main()
    {
    	string strTmp;
    	while(cin >> N >> M)
    	{
    		if(N == 0 && M == 0) { break; }
    		for(int i = 1; i <= N; i++)
    		{
    			cin >> strTmp;
    			for(int j = 1; j <= M; j++)
    			{
    				if(strTmp[j - 1] == '*') { pMap[i][j] = 1; }
    				else { pMap[i][j] = 0; }
    			}
    		}
    		int ans = 0;
    		memset(pVisited, false, sizeof(pVisited));
    		for(int i = 1; i <= N; i++)
    		{
    			for(int j = 1; j <= M; j++)
    			{
    				if(!pMap[i][j] && !pVisited[i][j])
    				{
    					dfs(i, j);
    					ans++;
    				}
    			}
    		}
    		cout << ans << endl;
    	}
    	return 0;
    }
    
    void dfs(int x, int y)
    {
    	pVisited[x][y] = true;
    	for(int i = 0; i < 8; i++)
    	{
    		int nx = x + dx[i];
    		int ny = y + dy[i];
    		if(nx >= 1 && nx <= N && ny >= 1 && ny <= M &&
    			!pMap[nx][ny] && !pVisited[nx][ny])
    		{ dfs(nx, ny); }
    	}
    }
    

      

    HDU 1495

    这道题目和POJ 3414非常的类似,但相较来说更简单,也是一道bfs水题。

    #include <iostream>
    #include <memory.h>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 128;
    
    struct Cola
    {
    	Cola(int _S = 0, int _N = 0, int _M = 0, int _ans = 0)
    	{ S = _S; N = _N; M = _M; ans = _ans; }
    
    	int S, N, M, ans;
    };
    
    int S, N, M;
    bool pVisited[MAX][MAX][MAX];
    queue<Cola> Q;
    
    Cola Opt(Cola Now, int k);
    bool Check(Cola Now);
    
    int main()
    {
    	while(cin >> S >> N >> M)
    	{
    		if(S == 0 && N == 0 && M == 0) { break; }
    		if(S & 1) { cout << "NO" << endl; }
    		else
    		{
    			bool bFlag = false;
    			memset(pVisited, false, sizeof(pVisited));
    			while(!Q.empty()) { Q.pop(); }  // 队列忘记清空
    			Q.push(Cola(S, 0, 0, 0)); pVisited[S][0][0] = true;
    			while(!Q.empty())
    			{
    				Cola Now = Q.front(); Q.pop();
    				if(Check(Now))
    				{
    					cout << Now.ans << endl;
    					bFlag = true;
    					break;
    				}
    				for(int i = 0; i < 6; i++)
    				{
    					Cola Next = Opt(Now, i);
    					if(!pVisited[Next.S][Next.N][Next.M])
    					{
    						Q.push(Cola(Next.S, Next.N, Next.M, Next.ans));
    						pVisited[Next.S][Next.N][Next.M] = true;
    					}
    				}
    			}
    			if(!bFlag) { cout << "NO" << endl; }
    		}
    	}
    	return 0;
    }
    
    Cola Opt(Cola Now, int k)
    {
    	if(k == 0)
    	{
    		Now.N += Now.S;
    		if(Now.N > N) { Now.S = Now.N - N; Now.N = N; }
    		else { Now.S = 0; }
    	}
    	if(k == 1)
    	{
    		Now.S += Now.N;
    		Now.N = 0;
    	}
    	if(k == 2)
    	{
    		Now.M += Now.S;
    		if(Now.M > M) { Now.S = Now.M - M; Now.M = M; }
    		else { Now.S = 0; }
    	}
    	if(k == 3)
    	{
    		Now.S += Now.M;
    		Now.M = 0;
    	}
    	if(k == 4)
    	{
    		Now.N += Now.M;
    		if(Now.N > N) { Now.M = Now.N - N; Now.N = N; }
    		else { Now.M = 0; }
    	}
    	if(k == 5)
    	{
    		Now.M += Now.N;
    		if(Now.M > M) { Now.N = Now.M - M; Now.M = M; }
    		else { Now.N = 0; }
    	}
    	Now.ans++;
    	return Now;
    }
    
    bool Check(Cola Now)
    {
    	int x = Now.S, y = Now.N, z = Now.M, p = S / 2;
    	return (x == p && y == p) || (x == p && z == p) || (y == p && z == p);
    }
    

      

    HDU 2612

    首先计算Y和M走到地图上每个点的最小时间,然后枚举每个点,计算Y和M走到该点时间和的最小值,最后结果乘以11分钟即可。

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    const int MAX = 256;
    
    const int dx[] = { 1, -1, 0, 0 };
    const int dy[] = { 0, 0, 1, -1 };
    
    struct Pos
    {
    	Pos(int _x = 0, int _y = 0, int _s = 0)
    	{ x = _x; y = _y; s = _s; }
    	
    	int x, y, s;
    };
    
    Pos SY, SM;
    int N, M;
    int pMap[MAX][MAX];
    int pAns[2][MAX][MAX];
    bool pVisited[MAX][MAX];
    queue<Pos> Q;
    
    void Solve(Pos S, int k);
    
    int main()
    {
    	string strTmp;
    	while(cin >> N >> M)
    	{
    		memset(pAns, -1, sizeof(pAns));
    		for(int i = 1; i <= N; i++)
    		{
    			cin >> strTmp;
    			for(int j = 1; j <= M; j++)
    			{
    				if(strTmp[j - 1] == '#') { pMap[i][j] = 1; }
    				else if(strTmp[j - 1] == '@') { pMap[i][j] = 2; }
    				else { pMap[i][j] = 0; }
    				if(strTmp[j - 1] == 'Y') { SY = Pos(i, j, 0); }
    				if(strTmp[j - 1] == 'M') { SM = Pos(i, j, 0); }
    			}
    		}
    		Solve(SY, 0); Solve(SM, 1);
    		int ans = 2147483647;
    		for(int i = 1; i <= N; i++)
    		{
    			for(int j = 1; j <= M; j++)
    			{
    				if(pMap[i][j] == 2 && pAns[0][i][j] != -1 && pAns[1][i][j] != -1)
    				{ ans = min(ans, pAns[0][i][j] + pAns[1][i][j]); }
    			}
    		}
    		cout << ans * 11 << endl;
    	}
    	return 0;
    }
    
    void Solve(Pos S, int k)
    {
    	while(!Q.empty()) { Q.pop(); }
    	memset(pVisited, false, sizeof(pVisited));
    	Q.push(S); pVisited[S.x][S.y] = true;
    	while(!Q.empty())
    	{
    		Pos Now = Q.front(); Q.pop();
    		if(pAns[k][Now.x][Now.y] == -1)
    		{ pAns[k][Now.x][Now.y] = Now.s; }
    		for(int i = 0; i < 4; i++)
    		{
    			int nx = Now.x + dx[i];
    			int ny = Now.y + dy[i];
    			if(nx >= 1 && nx <= N && ny >= 1 && ny <= M &&
    				!pVisited[nx][ny] && pMap[nx][ny] != 1)
    			{
    				Q.push(Pos(nx, ny, Now.s + 1));
    				pVisited[nx][ny] = true;
    			}
    		}
    	}
    }
    

      

    刷完这个专题,感觉对bfs的理解更加深入透彻了。

  • 相关阅读:
    [转帖]译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
    如何建立一个“绑定友好的”usercontrol--wpf
    安卓学习(三)
    安卓学习(二)
    Android学习1
    用伪代码梳理springboot
    用伪代码梳理javaweb从零开始
    用伪代码梳理spring源码
    java如何写出简洁代码
    JAVA修复微信官方SDK支付XXE漏洞
  • 原文地址:https://www.cnblogs.com/Ivy-End/p/4562068.html
Copyright © 2020-2023  润新知