深搜廣搜專題【DFS】【BFS】

深搜廣搜專題

又是一年專題時,這次的專題是BFS和DFS,我們剛加入acm時的噩夢,然而現在已經寫起來很舒服了(OS:那你還A不出題?)

BFS和DFS都是通過對所有的點進行遍歷來得到結果的,是一種比較暴力的方法,在平時較難的題目中一般不會出現。

 


A - Oil Deposits

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.

Input

The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket. 

Output

are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.

Sample Input

1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0

Sample Output

0
1
2
2

題意

給你一個二維平面圖,*代表空,@代表下有油層,@及其相鄰的@(包含斜對角)代表一個油田,問共有多少個不同的油田

思路

簡單的暴力搜索,需要注意斜對角線上相鄰的油也算在同一個油田中,在遍歷的時候我們先搜索到一塊油,對這塊油進行dfs,將與其相鄰的油都歸屬到同一個油田中,並將其重新標號爲*,防止重複。

AC代碼

//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
//#define INF 0x3f3f3f3f
//#define MAX 1e9
//#define N 1000005
#define ll long long
#define G 0
#define R 1
#define P 2
#define MOD 1000000007

using namespace std;

int n, m;
char map[101][101];

void dfs(int x, int y)
{
	map[x][y] = '*';
	int xt, yt;
	int next[8][2] = { {1,0},{0,1},{0,-1},{-1,0},{1,1},{1,-1},{-1,-1},{-1,1} };
	for(int i=0;i<8;i++)
	{
		xt = x + next[i][1];
		yt = y + next[i][0];
		if (xt >= m || xt<0 || yt >= n || yt < 0)continue;
		if (map[xt][yt] == '*')continue;
		dfs(xt, yt);
	}
}

int main()
{
	while(~scanf("%d%d",&m,&n))
	{
		getchar();
		if (!m)break;
		for (int i = 0; i < m; i++)
		{
				scanf("%s", &map[i]);
		}
		int count = 0;
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if(map[i][j]=='@')
				{
					count++;
					dfs(i, j);
				}
			}
		}
		printf("%d\n", count);
	}
	//system("PAUSE");
	return 0;
}

 

 


D - Prime Ring Problem 

A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. 

Note: the number of first circle should always be 1. 

 

Input

n (0 < n < 20). 

Output

The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order. 

You are to write a program that completes above process. 

Print a blank line after each case. 

Sample Input

6
8

Sample Output

Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2

題意

給我們一個環,從數字1開始,每兩個相鄰的數之和必須是一個質數,要你將可能的數按字典序升序輸出。

思路

質環問題,我們對每個點進行枚舉,判斷該點和上一個點之間是否滿足題目,若不滿足則及時剪枝,避免浪費時間,需要注意的是我們當判斷到最後一個點時需要將其與第一個點進行求和並求其是否是一個質數。對於本題來說最大數字之間的和不超過40,我們可以通過手動打出質數表來判斷一個數是否是質數。

AC代碼

//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#define INF 0x3f3f3f3f
//#define MAX 1e9
//#define N 1000005
#define ll long long
#define G 0
#define R 1
#define P 2
#define MOD 1000000007

using namespace std;

int prime[40] = { 0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0 };
int vis[21];
int n;

vector<int>seq;

void dfs(int x)
{
	if(seq.size()==n&&prime[x+seq[0]])
	{
		for (int i = 0; i<seq.size(); ++i)
		{
			cout << seq[i];
			if (i == seq.size() - 1)cout << endl;
			else cout << " ";
		}
		return;
	}
	for(int i=2;i<=n;i++)
	{
		if(prime[x+i]&&!vis[i])
		{
			vis[i] = true;
			seq.push_back(i);
			dfs(i);
			seq.pop_back();
			vis[i] = false;
		}
	}
}

int main()
{
	//for (int i = 0; i < 40; i++)
		//if (prime[i])cout << i << " ";
	ll c = 0;
	while(~scanf("%d",&n))
	{
		cout << "Case " << ++c << ":" << endl;
		memset(vis, 0, sizeof vis);
		seq.push_back(1);
		dfs(1);
		seq.pop_back();
		cout << endl;
	}
	//system("PAUSE");
	return 0;
}




 


 

E - A計劃

可憐的公主在一次次被魔王擄走一次次被騎士們救回來之後,而今,不幸的她再一次面臨生命的考驗。魔王已經發出消息說將在T時刻吃掉公主,因爲他聽信謠言說吃公主的肉也能長生不老。年邁的國王正是心急如焚,告招天下勇士來拯救公主。不過公主早已習以爲常,她深信智勇的騎士LJ肯定能將她救出。 
現據密探所報,公主被關在一個兩層的迷宮裏,迷宮的入口是S(0,0,0),公主的位置用P表示,時空傳輸機用#表示,牆用*表示,平地用.表示。騎士們一進入時空傳輸機就會被轉到另一層的相對位置,但如果被轉到的位置是牆的話,那騎士們就會被撞死。騎士們在一層中只能前後左右移動,每移動一格花1時刻。層間的移動只能通過時空傳輸機,且不需要任何時間。

Input

輸入的第一行C表示共有C個測試數據,每個測試數據的前一行有三個整數N,M,T。 N,M迷宮的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宮的第一層的佈置情況,後N*M表示迷宮第二層的佈置情況。

Output

如果騎士們能夠在T時刻能找到公主就輸出“YES”,否則輸出“NO”。

Sample Input

1
5 5 14
S*#*.
.#...
.....
****.
...#.

..*.P
#.*..
***..
...*.
*.#..

Sample Output

YES

題意

這次是一個廣搜問題,我們每一層的搜索對應一個時刻,在這個時刻內假設有足夠多的騎士移動至所有能到達的格子,循環往復,若找到公主,則檢查該點所對應的時刻是否滿足題意,若不滿足則輸出NO,還有一種情況就是公主根本不可達,我們在隊列內部所有點都無法繼續拓展直到隊列爲空後輸出NO。對於傳送門,當時沒有想到可能會有一個傳送門可以直接傳送到另一個傳送門的情況(掉入傳送門的嵌套中無法脫身什麼的,有點驚悚)WA了。

AC代碼

//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#define INF 0x3f3f3f3f
//#define MAX 1e9
//#define N 1000005
#define ll long long
#define G 0
#define R 1
#define P 2
#define MOD 1000000007

using namespace std;

int prime[40] = { 0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0 };
int vis[21];
int n;

vector<int>seq;

void dfs(int x)
{
	if(seq.size()==n&&prime[x+seq[0]])
	{
		for (int i = 0; i<seq.size(); ++i)
		{
			cout << seq[i];
			if (i == seq.size() - 1)cout << endl;
			else cout << " ";
		}
		return;
	}
	for(int i=2;i<=n;i++)
	{
		if(prime[x+i]&&!vis[i])
		{
			vis[i] = true;
			seq.push_back(i);
			dfs(i);
			seq.pop_back();
			vis[i] = false;
		}
	}
}

int main()
{
	//for (int i = 0; i < 40; i++)
		//if (prime[i])cout << i << " ";
	ll c = 0;
	while(~scanf("%d",&n))
	{
		cout << "Case " << ++c << ":" << endl;
		memset(vis, 0, sizeof vis);
		seq.push_back(1);
		dfs(1);
		seq.pop_back();
		cout << endl;
	}
	//system("PAUSE");
	return 0;
}




 


F - 勝利大逃亡

 

Ignatius被魔王抓走了,有一天魔王出差去了,這可是Ignatius逃亡的好機會. 

魔王住在一個城堡裏,城堡是一個A*B*C的立方體,可以被表示成A個B*C的矩陣,剛開始Ignatius被關在(0,0,0)的位置,離開城堡的門在(A-1,B-1,C-1)的位置,現在知道魔王將在T分鐘後回到城堡,Ignatius每分鐘能從一個座標走到相鄰的六個座標中的其中一個.現在給你城堡的地圖,請你計算出Ignatius能否在魔王回來前離開城堡(只要走到出口就算離開城堡,如果走到出口的時候魔王剛好回來也算逃亡成功),如果可以請輸出需要多少分鐘才能離開,如果不能則輸出-1. 

 

Input

輸入數據的第一行是一個正整數K,表明測試數據的數量.每組測試數據的第一行是四個正整數A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它們分別代表城堡的大小和魔王回來的時間.然後是A塊輸入數據(先是第0塊,然後是第1塊,第2塊......),每塊輸入數據有B行,每行有C個正整數,代表迷宮的佈局,其中0代表路,1代表牆.(如果對輸入描述不清楚,可以參考Sample Input中的迷宮描述,它表示的就是上圖中的迷宮) 

特別注意:本題的測試數據非常大,請使用scanf輸入,我不能保證使用cin能不超時.在本OJ上請使用Visual C++提交. 

Output

對於每組測試數據,如果Ignatius能夠在魔王回來前離開城堡,那麼請輸出他最少需要多少分鐘,否則輸出-1. 

Sample Input

1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0

Sample Output

11

題意

不就是上一題迷宮從兩層變成多層嘛效果一樣的呀 (暴言)

我們將上題的迷宮層數以及終點的判斷稍加修改,就可以AC本題啦!

其實並不能,那樣會TLE......我們可以看出,在某些情況下我們的主人公是無論如何都無法逃出昇天的,一種情況是出口就是一堵牆,我們無法穿過出口,第二種情況是主人公距離出口太遠,以至於毫無阻礙的情況下走向出口都無法離開,我們將這兩種情況加入代碼後,就真的AC了。

AC代碼

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#include <ctime>
#define INF 0x3f3f3f3f
//#define MAX 1e9
#define N 105
//#define ll long long
//#define MOD 1000000007

using namespace std;

int a, b, c, t;
int casle[51][51][51];

struct pos
{
	int x;
	int y;
	int z;
	int step;
};

queue<pos>que;

int bfs()
{
	//缺少前兩個特判會使程序TLE
	if (casle[a - 1][b - 1][c - 1])return -1;
	if (a + b + c - 3 > t)return -1;
	int book[51][51][51] = { 0 };
	book[0][0][0] = true;
	que.push({ 0,0,0 });
	while(!que.empty())
	{
		if (que.front().z == a - 1 && que.front().x == c - 1 && que.front().y == b - 1)
		{
			if (que.front().step <= t) return que.front().step;
		}
		int next[6][3] = { {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };
		for (int i = 0; i < 6; i++)
		{
			int tx = que.front().x + next[i][0];
			int ty = que.front().y + next[i][1];
			int tz = que.front().z + next[i][2];
			if (tx < 0 || ty < 0 || tz < 0 || tx >= c || ty >= b || tz >= a)continue;
			if (!book[tz][ty][tx] && casle[tz][ty][tx] != 1 && que.front().step + 1 <= t)
			{
				book[tz][ty][tx] = true;
				que.push({ tx,ty,tz,que.front().step + 1 });
			}
		}
		que.pop();
	}
	return -1;
}

int main()
{
	int C;
	scanf("%d", &C);
	while(C--)
	{
		scanf("%d%d%d%d", &a, &b, &c, &t);
		//注意清空
		while (!que.empty())que.pop();
		getchar();
		for (int lev = 0; lev < a; lev++)
		{
			for (int i = 0; i < b; i++)
			{
				for (int j = 0; j < c; j++)
					scanf("%d", &casle[lev][i][j]);
			}
		}
		printf("%d\n", bfs());
	}
	//system("PAUSE");
	return 0;
}

 


 G - Asteroids!

You're in space. 
You want to get home. 
There are asteroids. 
You don't want to hit them. 

Input

Input to this problem will consist of a (non-empty) series of up to 100 data sets. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets. 

A single data set has 5 components: 

Start line - A single line, "START N", where 1 <= N <= 10. 

Slice list - A series of N slices. Each slice is an N x N matrix representing a horizontal slice through the asteroid field. Each position in the matrix will be one of two values: 

'O' - (the letter "oh") Empty space 

'X' - (upper-case) Asteroid present 

Starting Position - A single line, "A B C", denoting the <A,B,C> coordinates of your craft's starting position. The coordinate values will be integers separated by individual spaces. 

Target Position - A single line, "D E F", denoting the <D,E,F> coordinates of your target's position. The coordinate values will be integers separated by individual spaces. 

End line - A single line, "END" 

The origin of the coordinate system is <0,0,0>. Therefore, each component of each coordinate vector will be an integer between 0 and N-1, inclusive. 

The first coordinate in a set indicates the column. Left column = 0. 

The second coordinate in a set indicates the row. Top row = 0. 

The third coordinate in a set indicates the slice. First slice = 0. 

Both the Starting Position and the Target Position will be in empty space. 
 

Output

For each data set, there will be exactly one output set, and there will be no blank lines separating output sets. 

A single output set consists of a single line. If a route exists, the line will be in the format "X Y", where X is the same as N from the corresponding input data set and Y is the least number of moves necessary to get your ship from the starting position to the target position. If there is no route from the starting position to the target position, the line will be "NO ROUTE" instead. 

A move can only be in one of the six basic directions: up, down, left, right, forward, back. Phrased more precisely, a move will either increment or decrement a single component of your current position vector by 1. 
 

Sample Input

START 1
O
0 0 0
0 0 0
END
START 3
XXX
XXX
XXX
OOO
OOO
OOO
XXX
XXX
XXX
0 0 1
2 2 1
END
START 5
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
XXXXX
XXXXX
XXXXX
XXXXX
XXXXX
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
0 0 0
4 4 4
END

Sample Output

1 0
3 4
NO ROUTE

題意

太空中有一大片小行星帶,你需要穿過它們,輸入空間中小行星分佈情況,問你是否可以穿過,若可以穿過輸出最短步數。

思路

這題完全,完全完全沒有什麼需要注意的地方......我要是說再把上面的AC代碼拿下來改改輸入的話應該不會被打死吧?不會嗎?太好了那就這麼辦吧!

AC代碼

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#include <ctime>
#define INF 0x3f3f3f3f
//#define MAX 1e9
#define N 105
//#define ll long long
//#define MOD 1000000007

using namespace std;

int a, b, n;
int sx, sy, sz, ex, ey, ez;

char space[11][11][11];

struct pos
{
	int x;
	int y;
	int z;
	int times;
};

queue<pos>que;

int bfs()
{
	int book[11][11][11] = { 0 };
	book[sz][sy][sx] = true;
	que.push({ sx,sy,sz,0 });
	while(!que.empty())
	{
		if (que.front().x == ex && que.front().y == ey && que.front().z == ez)
		{
			return que.front().times;
		}
		int next[6][3] = { { 1,0,0 },{ 0,1,0 },{ 0,0,1 },{ -1,0,0 },{ 0,-1,0 },{ 0,0,-1 } };
		for(int i=0;i<6;i++)
		{
			int tx = que.front().x + next[i][0];
			int ty = que.front().y + next[i][1];
			int tz = que.front().z + next[i][2];
			if (tx < 0 || ty < 0 || tz < 0 || tx >= n || ty >= n || tz >= n)continue;
			if(space[tz][ty][tx]!='X'&&!book[tz][ty][tx])
			{
				book[tz][ty][tx] = true;
				que.push({ tx,ty,tz,que.front().times + 1 });
			}
		}
		que.pop();
	}
	return -1;
}

int main()
{
	char c[10];
	while (~scanf("%s", c))
	{
		scanf("%d", &n);
		getchar();
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				scanf("%s", &space[i][j]);
			}
		}
		scanf("%d%d%d", &sx, &sy, &sz);
		scanf("%d%d%d", &ex, &ey, &ez);
		getchar();
		scanf("%s", c);
		//注意清空
		while (!que.empty())que.pop();
		int temp = bfs();
		if (temp != -1)
			printf("%d %d\n", n, temp);
		else printf("NO ROUTE\n");
	}
	//system("PAUSE");
	return 0;
}

 


H - A strange lift

There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button "UP" , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button "DOWN" , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can't go up high than N,and can't go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button "UP", and you'll go up to the 4 th floor,and if you press the button "DOWN", the lift can't do it, because it can't go down to the -2 th floor,as you know ,the -2 th floor isn't exist. 
Here comes the problem: when you are on floor A,and you want to go to floor B,how many times at least he has to press the button "UP" or "DOWN"? 

Input

The input consists of several test cases.,Each test case contains two lines. 
The first line contains three integers N ,A,B( 1 <= N,A,B <= 200) which describe above,The second line consist N integers k1,k2,....kn. 
A single 0 indicate the end of the input.

Output

For each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can't reach floor B,printf "-1".

Sample Input

5 1 5
3 3 1 2 5
0

Sample Output

3

題意

一部迷之電梯,在每一層開始移動時只按照該層的指定移動層數上下移動, 問有沒有可能從某一樓到另外一樓。

思路

這題不再是遍歷圖的問題了,而是有規律的線性移動,我們將dfs的移動方式稍加修改,將每一層的移動位置定爲該層輸入的指定移動層數,使其移動規律符合題意便可。需要注意的是電梯僅能在輸入的層中間移動,要是捅穿屋頂了或者扎進地下的話不算。

AC代碼

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#include <ctime>
#define INF 0x3f3f3f3f
//#define MAX 1e9
#define N 105
//#define ll long long
//#define MOD 1000000007

using namespace std;

int a, b, n;

struct pos
{
	int floor;
	int times;
};

queue<pos>que;

int moves[205];

int bfs()
{
	int book[205] = { 0 };
	book[a] = true;
	que.push({ a,0 });
	while(!que.empty())
	{
		int temp = que.front().floor;
		if (temp == b)return que.front().times;
		if (temp - moves[temp] > 0)
		{
			if (!book[temp - moves[temp]])
			{
				book[temp - moves[temp]] = true;
				que.push({ temp - moves[temp],que.front().times + 1 });
			}
		}
		if (temp + moves[temp] <= n)
		{
			if(!book[temp + moves[temp]])
			{
				book[temp + moves[temp]] = true;
				que.push({ temp + moves[temp] ,que.front().times + 1 });
			}
		}
		que.pop();
	}
	return -1;
}

int main()
{
	while (~scanf("%d", &n))
	{
		if (!n)break;
		scanf("%d%d", &a, &b);
		//注意清空
		while (!que.empty())que.pop();
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &moves[i]);
		}
		printf("%d\n", bfs());
	}
	//system("PAUSE");
	return 0;
}

 

 


I - Catch That Cow

 

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting. 

* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute 
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute. 

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers: N and K

Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

題意

在一條直線上,一個帶了閃現的農夫要抓牛,這個農夫有三種移動方式分別爲向前向後一步,在當前的點座標上閃現到兩倍當前座標的位置,問最短移動多少次能抓到。

思路

又到了愉快的修改前一道題代碼的時間啦!

我們將上題的移動方式改爲本題移動方式,並且將上題中的移動範圍限制去除即可。需要注意的是我們在當前位置不比牛大時有三種移動方式,前後移動和向前閃現,在當前位置比牛大後便僅有向後移動是有意義的,此處可以剪枝,除去無意義的判斷。什麼,你問我要是不剪會怎麼樣?我咋知道,萬一TLE了呢?

AC代碼

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
#include <bitset>
#include <queue>
#include <ctime>
#define INF 0x3f3f3f3f
//#define MAX 1e9
#define N 105
//#define ll long long
//#define MOD 1000000007

using namespace std;

int n, k;

struct pos
{
	int x;
	int min;
};

queue<pos>que;

int move(int x,int times)
{
		switch(times)
		{
		case 2:return x * 2;
		case 1:return x + 1;
		case 0:return x - 1;
		}
}

int bfs()
{
	int book[200000] = { 0 };
	book[n] = true;
	que.push({ n, 0 });
	while(!que.empty())
	{
		if (que.front().x == k )
		{
			return que.front().min;
		}
		int tx = que.front().x;
		int t;
		if (tx < k)t = 3;
		else t = 1;
		while (t--)
		{
			int x = move(tx, t);
			if(!book[x])
			{
				book[x] = true;
				que.push({ x,que.front().min + 1 });
			}
		}
		que.pop();
	}
}

int main()
{
	while (~scanf("%d%d", &n, &k))
	{
		//注意清空
		while (!que.empty())que.pop();
		printf("%d\n", bfs());
	}
	//system("PAUSE");
	return 0;
}

 


本次題解中還有B題和C題沒有AC出來,B題迷之坑,花了我一天的時間測試各種能想到以及找到的樣例都無法定位BUG,如果我能AC就補題解吧!嗯!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章