暑假训练DAY8(BFS)

Oil Deposits


Time Limit: 2 Seconds      Memory Limit: 65536 KB


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 file 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

For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they 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

搜索的模板题了。不解释。我代码不知道为什么样例过不去,却可以过?????????

#include<stdio.h>
#include<string.h>
struct oil{
	int x,y,type;//1有油2无油 
}plot[105][105]; //先x后y 
int flag[105][105]={0};
int much,w,h;
int solve(int x,int y)
{
	int p,q,x0,x1,y0,y1;
	flag[x][y]=1;
	if(y-1>=0) y0=y-1;
	else y0=0;
	if(y+1<h) y1=y+1;
	else y1=h-1;
	if(x-1>=0) x0=x-1;
	else x0=0;
	if(x+1<w) x1=x+1;
	else x1=w-1; 
	for(q=y0;q<=y1;q++)
	{
		for(p=x0;p<=x1;p++)
		{
			if(flag[p][q]==0&&plot[p][q].type==1)
			{
				--much;
				solve(p,q);
			}	
		}
	}
}
int main()
{
	int p,q;
	char ty;
	while(~scanf("%d%d",&h,&w))
	{
		if(h==0&&w==0) break;
		much=0;
		memset(flag,0,sizeof(flag));
		memset(plot,0,sizeof(plot));
		getchar();
		for(q=0;q<h;q++)
		{
			for(p=0;p<w;p++)
			{
				scanf("%c",&ty);
				if(ty=='@') {plot[p][q].type=1;much++;}
				if(ty=='*') plot[p][q].type=2;
				//printf("%c ",ty);
			}
			//printf("\n");
			getchar();
		}
		for(q=0;q<h;q++)
		{
			for(p=0;p<w;p++)
			{
				if(flag[p][q]==0&&plot[p][q].type==1)
				solve(p,q);
				//printf("%d ",plot[p][q].type);
			}
			//printf("\n");
		}
		printf("%d\n",much);
	}
}
//

 

Prime Path

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 27152 Accepted: 14871

Description

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 
— It is a matter of security to change such things every now and then, to keep the enemy in the dark. 
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime. 

Now, the minister of finance, who had been eavesdropping, intervened. 
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 
— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 
— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 

1033
1733
3733
3739
3779
8779
8179

The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

Input

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

Output

One line for each case, either with a number stating the minimal cost or containing the word Impossible.

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0

Source

Northwestern Europe 2006

素数环,也算是模板题了。需要注意的是,这里的时间卡得很紧,如果只是变一位就不要全部修改一遍了,可能超时

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
struct node{
	int u;
	int depth;
};

int judge[]={
1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,
1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,
1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,
1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619,1621,1627,1637,1657,
1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,
1861,1867,1871,1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003,2011,2017,
2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,2203,2207,
2213,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357,2371,2377,
2381,2383,2389,2393,2399,2411,2417,2423,2437,2441,2447,2459,2467,2473,2477,2503,2521,2531,2539,2543,2549,2551,2557,
2579,2591,2593,2609,2617,2621,2633,2647,2657,2659,2663,2671,2677,2683,2687,2689,2693,2699,2707,2711,2713,2719,2729,
2731,2741,2749,2753,2767,2777,2789,2791,2797,2801,2803,2819,2833,2837,2843,2851,2857,2861,2879,2887,2897,2903,2909,
2917,2927,2939,2953,2957,2963,2969,2971,2999,3001,3011,3019,3023,3037,3041,3049,3061,3067,3079,3083,3089,3109,3119,
3121,3137,3163,3167,3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257,3259,3271,3299,3301,3307,3313,3319,
3323,3329,3331,3343,3347,3359,3361,3371,3373,3389,3391,3407,3413,3433,3449,3457,3461,3463,3467,3469,3491,3499,3511,
3517,3527,3529,3533,3539,3541,3547,3557,3559,3571,3581,3583,3593,3607,3613,3617,3623,3631,3637,3643,3659,3671,3673,
3677,3691,3697,3701,3709,3719,3727,3733,3739,3761,3767,3769,3779,3793,3797,3803,3821,3823,3833,3847,3851,3853,3863,
3877,3881,3889,3907,3911,3917,3919,3923,3929,3931,3943,3947,3967,3989,4001,4003,4007,4013,4019,4021,4027,4049,4051,
4057,4073,4079,4091,4093,4099,4111,4127,4129,4133,4139,4153,4157,4159,4177,4201,4211,4217,4219,4229,4231,4241,4243,
4253,4259,4261,4271,4273,4283,4289,4297,4327,4337,4339,4349,4357,4363,4373,4391,4397,4409,4421,4423,4441,4447,4451,
4457,4463,4481,4483,4493,4507,4513,4517,4519,4523,4547,4549,4561,4567,4583,4591,4597,4603,4621,4637,4639,4643,4649,
4651,4657,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751,4759,4783,4787,4789,4793,4799,4801,4813,4817,4831,4861,
4871,4877,4889,4903,4909,4919,4931,4933,4937,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003,5009,5011,5021,5023,
5039,5051,5059,5077,5081,5087,5099,5101,5107,5113,5119,5147,5153,5167,5171,5179,5189,5197,5209,5227,5231,5233,5237,
5261,5273,5279,5281,5297,5303,5309,5323,5333,5347,5351,5381,5387,5393,5399,5407,5413,5417,5419,5431,5437,5441,5443,
5449,5471,5477,5479,5483,5501,5503,5507,5519,5521,5527,5531,5557,5563,5569,5573,5581,5591,5623,5639,5641,5647,5651,
5653,5657,5659,5669,5683,5689,5693,5701,5711,5717,5737,5741,5743,5749,5779,5783,5791,5801,5807,5813,5821,5827,5839,
5843,5849,5851,5857,5861,5867,5869,5879,5881,5897,5903,5923,5927,5939,5953,5981,5987,6007,6011,6029,6037,6043,6047,
6053,6067,6073,6079,6089,6091,6101,6113,6121,6131,6133,6143,6151,6163,6173,6197,6199,6203,6211,6217,6221,6229,6247,
6257,6263,6269,6271,6277,6287,6299,6301,6311,6317,6323,6329,6337,6343,6353,6359,6361,6367,6373,6379,6389,6397,6421,
6427,6449,6451,6469,6473,6481,6491,6521,6529,6547,6551,6553,6563,6569,6571,6577,6581,6599,6607,6619,6637,6653,6659,
6661,6673,6679,6689,6691,6701,6703,6709,6719,6733,6737,6761,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833,6841,
6857,6863,6869,6871,6883,6899,6907,6911,6917,6947,6949,6959,6961,6967,6971,6977,6983,6991,6997,7001,7013,7019,7027,
7039,7043,7057,7069,7079,7103,7109,7121,7127,7129,7151,7159,7177,7187,7193,7207,7211,7213,7219,7229,7237,7243,7247,
7253,7283,7297,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411,7417,7433,7451,7457,7459,7477,7481,7487,7489,7499,
7507,7517,7523,7529,7537,7541,7547,7549,7559,7561,7573,7577,7583,7589,7591,7603,7607,7621,7639,7643,7649,7669,7673,
7681,7687,7691,7699,7703,7717,7723,7727,7741,7753,7757,7759,7789,7793,7817,7823,7829,7841,7853,7867,7873,7877,7879,
7883,7901,7907,7919,7927,7933,7937,7949,7951,7963,7993,8009,8011,8017,8039,8053,8059,8069,8081,8087,8089,8093,8101,
8111,8117,8123,8147,8161,8167,8171,8179,8191,8209,8219,8221,8231,8233,8237,8243,8263,8269,8273,8287,8291,8293,8297,
8311,8317,8329,8353,8363,8369,8377,8387,8389,8419,8423,8429,8431,8443,8447,8461,8467,8501,8513,8521,8527,8537,8539,
8543,8563,8573,8581,8597,8599,8609,8623,8627,8629,8641,8647,8663,8669,8677,8681,8689,8693,8699,8707,8713,8719,8731,
8737,8741,8747,8753,8761,8779,8783,8803,8807,8819,8821,8831,8837,8839,8849,8861,8863,8867,8887,8893,8923,8929,8933,
8941,8951,8963,8969,8971,8999,9001,9007,9011,9013,9029,9041,9043,9049,9059,9067,9091,9103,9109,9127,9133,9137,9151,
9157,9161,9173,9181,9187,9199,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283,9293,9311,9319,9323,9337,9341,9343,
9349,9371,9377,9391,9397,9403,9413,9419,9421,9431,9433,9437,9439,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533,
9539,9547,9551,9587,9601,9613,9619,9623,9629,9631,9643,9649,9661,9677,9679,9689,9697,9719,9721,9733,9739,9743,9749,
9767,9769,9781,9787,9791,9803,9811,9817,9829,9833,9839,9851,9857,9859,9871,9883,9887,9901,9907,9923,9929,9931,9941,
9949,9967,9973};

inline int is_prime(int x)
{
	return count(judge,judge+1061,x);
}
inline int get_num(int* arr)
{
	int temp=0;
	for(int i=0;i<4;i++)
	{
		temp+=arr[i]*pow(10,3-i);
	}
	return temp;
}
inline void get_arr(int x,int* arr)
{
	arr[0]=x/1000;
	arr[1]=x%1000/100;
	arr[2]=x%100/10;
	arr[3]=x%10;
}

int flag[10000];
int bfs(int a,int b)
{
	queue<node> q;
	node s;
	s.u=a,s.depth=0;
	q.push(s);
	flag[a]=1;
	while(!q.empty())
	{
		node x=q.front();
		q.pop();
		//cout<<x.u<<endl;
		if(x.u==b) return x.depth;
		//千位 
		for(int j=1;j<=9;j++)
		{
			int nnum=x.u-x.u/1000*1000+j*1000;
			if(!flag[nnum]&&is_prime(nnum))
			{
				node m;m.u=nnum;m.depth=x.depth+1;
				flag[nnum]=1;
				q.push(m);
			}
		}
		//百位 
		for(int j=0;j<=9;j++)
		{
			int nnum=x.u-x.u%1000/100*100+j*100;
			if(!flag[nnum]&&is_prime(nnum))
			{
				node m;m.u=nnum;m.depth=x.depth+1;
				flag[nnum]=1;
				q.push(m);
			}
		}
		//十位 
		for(int j=0;j<=9;j++)
		{
			int nnum=x.u-x.u%100/10*10+j*10;
			if(!flag[nnum]&&is_prime(nnum))
			{
				node m;m.u=nnum;m.depth=x.depth+1;
				flag[nnum]=1;
				q.push(m);
			}
		}
		//个位 
		for(int j=0;j<=9;j++)
		{
			int nnum=x.u-x.u%10+j;
			if(!flag[nnum]&&is_prime(nnum))
			{
				node m;m.u=nnum;m.depth=x.depth+1;
				flag[nnum]=1;
				q.push(m);
			}
		}	
	}
	return -1;
}
int main()
{
	int a,b;
	
	int t;
	cin>>t;
	while(t--)
	{
		
		memset(flag,0,sizeof(flag));
		cin>>a>>b;
		int ans=bfs(a,b);
		if(ans==-1) cout<<"Impossible"<<endl;
		else cout<<ans<<endl;
	}
	return 0;
}

Catch That Cow

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20313    Accepted Submission(s): 5935


 

Problem Description

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.

 

 

Source

USACO 2007 Open Silver

这题直接就是一维了。。简单得不成样子,需要注意得是,因为他可以一次直接把自己的位置加倍,所以标记的数组记得开一倍一点

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
struct node{
	int x;
	int tim;
};
int flag[200010];
queue<node> q;
int bfs(int n,int k)
{
	while(!q.empty()) q.pop();
	node beg;
	flag[n]=1;
	beg.x=n;
	beg.tim=0;
	q.push(beg);
	while(!q.empty())
	{
		node u;
		u=q.front();
		q.pop();
		//cout<<u.x<<endl;
		if(u.x==k) return u.tim;
		node p;
		p.x=u.x+1;
		p.tim=u.tim+1;
		if(p.x>=0&&p.x<=200000&&!flag[p.x])
		q.push(p),flag[p.x]=1;
		p.x=u.x*2;
		p.tim=u.tim+1;
		if(p.x>=0&&p.x<=200000&&!flag[p.x])
		q.push(p),flag[p.x]=1;
		p.x=u.x-1;
		p.tim=u.tim+1;
		if(p.x>=0&&p.x<=200000&&!flag[p.x])
		q.push(p),flag[p.x]=1;
	} 
}
int main()
{
	int n,k;
	while(cin>>n>>k)
	{
		memset(flag,0,sizeof(flag));
		cout<<bfs(n,k)<<endl;
	}
	return 0;
}

胜利大逃亡(续)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10777    Accepted Submission(s): 3911


 

Problem Description

Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。

 

 

Input

每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:

. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J

每组测试数据之间有一个空行。

 

 

Output

针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。

 

 

Sample Input

 

4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*

 

 

Sample Output

 

16 -1

 

 

Author

LL

 

 

Source

ACM暑期集训队练习赛(三)

 

 

Recommend

linle

这题是我第一次接触状态压缩,感觉玄妙异常。

我们可以知道,一个人对一把钥匙的情况只有两种即持有和未持有,因此可以用0和1表示

因此想到二进制,每一位代表一把不同的钥匙得到一把钥匙可以将他现在的钥匙持有情况key和下一把钥匙(编号i)作'或'处理

key|(1<<i)

而能否打开门就可以用到'与'操作key&(1<<i),如返回0则无法开门,非零则可开门。

还有一点需要注意的是这样可能会走重复的路,因此标记改成了flag[x][y][key]同时对x,y,key的共同状态进行标记

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
const int INF=0x3f3f3f3f;
struct node{
	int x,y,depth;
	int key;
	node(int x=0,int y=0,int depth=0,int key=0):x(x),y(y),depth(depth),key(key){}
};
int sx,sy,n,mm;
int t;
int mve[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int flag[50][50][2000];
char m[50][50];
queue<node> q;
int check(node u)
{
	char c=m[u.x][u.y];
	if(u.x>=1&&u.x<=n&&u.y>=1&&u.y<=mm&&c!='*'&&!flag[u.x][u.y][u.key]) return 1;
	return 0;
}
int bfs()
{
	while(!q.empty()) q.pop();
	node beg(sx,sy,0,0);
	flag[sx][sy][0]=1;
	q.push(beg);
	while(!q.empty())
	{
		node fir=q.front();
		q.pop();
		if(fir.depth>=t) break;
		for(int i=0;i<4;i++)
		{
			node nxt;
			nxt.x=fir.x+mve[i][0];
			nxt.y=fir.y+mve[i][1];
			nxt.depth=fir.depth+1;
			nxt.key=fir.key;
			char c=m[nxt.x][nxt.y];
			if(!check(nxt)) continue;
			if(c>='a'&&c<='z')
			{
				nxt.key=(nxt.key|(1<<(c-'a')));
			}
			if(c>='A'&&c<='Z')
			{
				if((nxt.key&(1<<(c-'A')))!=((1<<(c-'A'))))
				continue;
			}
			if(c=='^')
			{
				return nxt.depth; 
			}
			q.push(nxt);
			flag[nxt.x][nxt.y][nxt.key]=1;
		}
	}
	return INF;
} 
int main()
{
	
	while(cin>>n>>mm>>t)
	{
		memset(flag,0,sizeof(flag));
		int i;
		for(i=1;i<=n;i++)
		{
			scanf("%s",m[i]+1);
		}
		for(i=1;i<=n;i++)
		{
			for(int j=1;j<=mm;j++)
			{
				if(m[i][j]=='@')
				{
					sx=i;
					sy=j;
					break;
				}
			}
		}
		
		int ans=bfs();
		if(ans<t) cout<<ans<<endl;
		else cout<<"-1"<<endl;
	}
	return 0;
}

1726: 你经历过绝望吗?两次!

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 860     Solved: 291    


Description

4月16日,日本熊本地区强震后,受灾严重的阿苏市一养猪场倒塌,幸运的是,猪圈里很多头猪依然坚强存活。当地15名消防员耗时一天解救围困的“猪坚强”。不过与在废墟中靠吃木炭饮雨水存活36天的中国汶川“猪坚强”相比,熊本的猪可没那么幸运,因为它们最终还是没能逃过被送往屠宰场的命运。

我们假设“猪坚强”被困在一个N*M的废墟中,其中“@”表示“猪坚强”的位置,“.”表示可以直接通过的空地,“#”表示不能拆毁的障碍物,“*”表示可以拆毁的障碍物,那么请问消防员至少要拆毁多少个障碍物,才能从废墟中救出“猪坚强”送往屠宰场?(当“猪坚强”通过空地或被拆毁的障碍物移动到废墟边缘时,视作被救出废墟)

 

Input

多组数据,第一行有一个整数T,表示有T组数据。(T<=100)

以下每组数据第一行有两个整数N和M。(1<=N,M<=100)

接着N行,每行有一个长度为M的字符串。

 

Output

一个整数,为最少拆毁的障碍物数量,如果不能逃离废墟,输出-1。

 

Sample Input

3
3 3
###
#@*
***
3 4
####
#@.*
**.*
3 3
.#.
#@#
.#.

Sample Output

1
0
-1

Hint

Source

中南大学第十届大学生程序设计竞赛

Author

LVV

BFS模板题啦,用以拆的墙的数量为标准用优先队列维护一下就好了。

代码:

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct node{
	int x,y;
	int dtory;
	
};
bool operator<(node b,node a)
{
	return b.dtory>a.dtory;
}
priority_queue<node> q;
char map[205][205];bool flag[205][205];
int mve[2][4]={{0,0,1,-1},{1,-1,0,0}};
int n,m;
int bfs(int x,int y)
{
	while(!q.empty()) q.pop();
	node k;
	flag[x][y]=1;
	k.x=x,k.y=y,k.dtory=0;
	q.push(k);
	while(!q.empty())
	{
		node temp;
		temp=q.top();
		q.pop();
		if(temp.x==n-1||temp.y==m-1||temp.x==0||temp.y==0) return temp.dtory;
		for(int i=0;i<4;i++)
		{
			int jx=temp.x+mve[0][i];
			int jy=temp.y+mve[1][i];
			if(!flag[jx][jy]&&map[jx][jy]!='#')
			{
				node j;
				if(map[jx][jy]=='*')
				{
					j.dtory=temp.dtory+1;
				}
				else j.dtory=temp.dtory;
				j.x=jx,j.y=jy;
				flag[jx][jy]=1;
				q.push(j);
			}
		}
	}
	return -1;
} 
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(flag,0,sizeof(flag));
		scanf("%d%d",&n,&m);
		int i,j;
		int objx,objy;
		for(i=0;i<n;i++)
		{
			scanf("%s",map[i]);
			for(j=0;j<m;j++)
			{
				if(map[i][j]=='@') objx=i,objy=j;
			}
		}
		int ans=bfs(objx,objy);
		printf("%d\n",ans);
	}
}

 

C. The Labyrinth

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a rectangular field of n × m cells. Each cell is either empty or impassable (contains an obstacle). Empty cells are marked with '.', impassable cells are marked with '*'. Let's call two empty cells adjacent if they share a side.

Let's call a connected component any non-extendible set of cells such that any two of them are connected by the path of adjacent cells. It is a typical well-known definition of a connected component.

For each impassable cell (x, y) imagine that it is an empty cell (all other cells remain unchanged) and find the size (the number of cells) of the connected component which contains (x, y). You should do it for each impassable cell independently.

The answer should be printed as a matrix with n rows and m columns. The j-th symbol of the i-th row should be "." if the cell is empty at the start. Otherwise the j-th symbol of the i-th row should contain the only digit —- the answer modulo 10. The matrix should be printed without any spaces.

To make your output faster it is recommended to build the output as an array of n strings having length m and print it as a sequence of lines. It will be much faster than writing character-by-character.

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printfinstead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

Input

The first line contains two integers n, m (1 ≤ n, m ≤ 1000) — the number of rows and columns in the field.

Each of the next n lines contains m symbols: "." for empty cells, "*" for impassable cells.

Output

Print the answer as a matrix as described above. See the examples to precise the format of the output.

Examples

input

Copy

3 3
*.*
.*.
*.*

output

Copy

3.3
.5.
3.3

input

Copy

4 5
**..*
..***
.*.*.
*.*.*

output

Copy

46..3
..732
.6.4.
5.4.3

这题如果对每个'*'搜索,铁超时,因此决定先计算每个联通块的大小再用并查集连接到初始的那个'.'上并把联通块的大小记录到那个初始的点上,再对每个'*'加上上下左右的联通块的大小再加1即可,需要注意的是这里他的四周的联通块可能有连通,所以要记得标记,不要加重复了(最后的每个块的数量记得对10求模)。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
struct node{
	int x,y;
	node(int x=0,int y=0):x(x),y(y){}
};
queue<node> q;
int mve[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int flag[1005][1005];
int ans[1005][1005];
node fa[1005][1005];
int n,mm;
char m[1005][1005];
int check(node t)
{
	if(t.x>=1&&t.y>=1&&t.x<=n&&t.y<=mm&&!flag[t.x][t.y]&&m[t.x][t.y]=='.') return 1;
	return 0;
}
void bfs(int x0,int y0)
{
	node beg(x0,y0);
	flag[x0][y0]=1;
	q.push(beg);
	fa[x0][y0].x=x0;
	fa[x0][y0].y=y0;
	int size=1;
	while(!q.empty())
	{
		node u=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			node nxt(u.x+mve[i][0],u.y+mve[i][1]);
			if(!check(nxt)) continue;
			q.push(nxt);
			++size;
			flag[nxt.x][nxt.y]=1;
			fa[nxt.x][nxt.y].x=x0;
			fa[nxt.x][nxt.y].y=y0;
		}
	}
	ans[x0][y0]=size;
}
int vis[4];
inline int get_ans(int x,int y)
{
	memset(vis,-1,sizeof(vis));
	int sum=1;
	int cnt=0;
	for(int i=0;i<4;i++)
	{
		int xx=x+mve[i][0];
		int yy=y+mve[i][1];
		node u=fa[xx][yy];
		int Hash=u.x*1005+u.y;
		if(xx>=1&&xx<=n&&yy>=1&&yy<=mm&&m[xx][yy]=='.'&&vis[0]!=Hash&&vis[1]!=Hash&&vis[2]!=Hash&&vis[3]!=Hash) 
		{
			vis[cnt++]=Hash;
			sum+=ans[u.x][u.y];
		}
	}
	return sum;
}
int main()
{
	while(cin>>n>>mm)
	{
		memset(flag,0,sizeof(flag));
		int i,j;
		for(i=1;i<=n;i++)
		{
			scanf("%s",m[i]+1);
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=mm;j++)
			{
				if(!flag[i][j]&&m[i][j]=='.')
				bfs(i,j);
			}
		} 
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=mm;j++)
			{
				if(m[i][j]=='*')
				printf("%d",get_ans(i,j)%10);
				else printf(".");
			}
			printf("\n");
		}
	}
	return 0;
}

 

1224: ACM小组的古怪象棋

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 921     Solved: 385    


Description

ACM小组的Samsara和Staginner对中国象棋特别感兴趣,尤其对马(可能是因为这个棋子的走法比较多吧)的使用进行深入研究。今天他们又在 构思一个古怪的棋局:假如Samsara只有一个马了,而Staginner又只剩下一个将,两个棋子都在棋盘的一边,马不能出这一半棋盘的范围,另外这 一半棋盘的大小很奇特(n行m列)。Samsara想知道他的马最少需要跳几次才能吃掉Staginner的将(我们假定其不会移动)。当然这个光荣的任 务就落在了会编程的你的身上了。

Input

每组数据一行,分别为六个用空格分隔开的正整数n,m,x1,y1,x2,y2分别代表棋盘的大小n,m,以及将的坐标和马的坐标。(1<=x1,x2<=n<=20,1<=y1,y2<=m<=20,将和马的坐标不相同)

Output

输出对应也有若干行,请输出最少的移动步数,如果不能吃掉将则输出“-1”(不包括引号)。

Sample Input

8 8 5 1 4 5

Sample Output

3

Hint

Source

CSU Monthly 2011 Dec.

裸搜索,运动方式改一下就好了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
int mve[8][2]={{2,1},{1,2},{1,-2},{2,-1},{-1,2},{-2,1},{-2,-1},{-1,-2}};
int flag[25][25];
int n,m;
struct node{
	int x,y;
	int step;
	node(int x=0,int y=0,int step=0):x(x),y(y),step(step){}
};
int check(node u)
{
	if(u.x>=1&&u.x<=n&&u.y>=1&&u.y<=m&&!flag[u.x][u.y]) return 1;
	return 0;
} 
queue<node> q;
int bfs(int sx,int sy,int ex,int ey)
{
	while(!q.empty()) q.pop();
	node beg(sx,sy,0);
	q.push(beg);
	flag[sx][sy]=1;
	while(!q.empty())
	{
		node u=q.front();
		q.pop();
		if(u.x==ex&&u.y==ey) return u.step;
		for(int i=0;i<8;i++)
		{
			node nxt(u.x+mve[i][0],u.y+mve[i][1],u.step+1);
			if(check(nxt))
			{
				q.push(nxt);
				flag[nxt.x][nxt.y]=1;
			}
		}
	}
	return -1;
}
int main()
{
	int sx,sy,ex,ey;
	while(cin>>n>>m>>ex>>ey>>sx>>sy)
	{
		memset(flag,0,sizeof(flag));
		int ans=bfs(sx,sy,ex,ey);
		cout<<ans<<endl;
	}
	return 0;
}

2031: Barareh on Fire

Submit Page    Summary    Time Limit: 3 Sec     Memory Limit: 512 Mb     Submitted: 647     Solved: 192    


Description

The Barareh village is on fire due to the attack of the virtual enemy. Several places are already on fire and the fire is spreading fast to other places. Khorzookhan who is the only person remaining alive in the war with the virtual enemy, tries to rescue himself by reaching to the only helicopter in the Barareh villiage. Suppose the Barareh village is represented by an n × m grid. At the initial time, some grid cells are on fire. If a cell catches fire at time x, all its 8 vertex-neighboring cells will catch fire at time x + k. If a cell catches fire, it will be on fire forever. At the initial time, Khorzookhan stands at cell s and the helicopter is located at cell t. At any time x, Khorzookhan can move from its current cell to one of four edge-neighboring cells, located at the left, right, top, or bottom of its current cell if that cell is not on fire at time x + 1. Note that each move takes one second. Your task is to write a program to find the shortest path from s to t avoiding fire.

Input

There are multiple test cases in the input. The first line of each test case contains three positive integers n, m and k (1 ⩽ n,m,k ⩽ 100), where n and m indicate the size of the test case grid n × m, and k denotes the growth rate of fire. The next n lines, each contains a string of length m, where the jth character of the ith line represents the cell (i, j) of the grid. Cells which are on fire at time 0, are presented by character “f”. There may exist no “f” in the test case. The helicopter and Khorzookhan are located at cells presented by “t” and “s”, respectively. Other cells are filled by “-” characters. The input terminates with a line containing “0 0 0” which should not be processed.

Output

For each test case, output a line containing the shortest time to reach t from s avoiding fire. If it is impossible to reach t from s, write “Impossible” in the output.

Sample Input

7 7 2
f------
-f---f-
----f--
-------
------f
---s---
t----f-
3 4 1
t--f
--s-
----
2 2 1
st
f-
2 2 2
st
f-
0 0 0

Sample Output

4
Impossible
Impossible
1

Hint

Source

ATRC2017

两遍bfs,先处理处理出火的蔓延情况,然后每次搜索的时候都对时间和这点火蔓延到的时间进行对比就好了。

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
//从s到t 
const int maxn=200;
struct node{
	int x,y,step;
};
int fire[105][105],speed;
bool flag[105][105];
queue<node> fir;
int n,m;//n行m列 
node be,en;
queue<node> road;
int movf[2][8]={{0,0,1,1,1,-1,-1,-1},{1,-1,1,-1,0,1,-1,0}};
int movp[2][4]={{0,0,1,-1},{1,-1,0,0}};
void bfs_fire()
{
	node temp;
	while(!fir.empty())
	{
		temp=fir.front();
		fir.pop();
		int when;
		when=fire[temp.x][temp.y]+speed;
		for(int i=0;i<8;i++)
		{
			int tx,ty;
			
			tx=temp.x+movf[0][i];
			ty=temp.y+movf[1][i];
			//if(fire[temp.x][temp.y]==0) printf("%d %d\n",tx,ty);
			if(fire[tx][ty]>when&&tx>=1&&tx<=n&&ty>=1&&ty<=m)
			{
				node t;
				t.x=tx;
				t.y=ty;
				fire[tx][ty]=when;
				fir.push(t);
			}
		}
	}
}
int bfs_road()
{
	node temp;
	road.push(be);
	while(!road.empty())
	{
		temp=road.front();
		road.pop();
		if(temp.x==en.x&&temp.y==en.y)
		{
			return temp.step;
		}
		else for(int i=0;i<4;i++)
		{
			int tx,ty;
			tx=temp.x+movp[0][i];
			ty=temp.y+movp[1][i];
			if(tx<=n&&tx>=1&&ty<=m&&ty>=1&&fire[tx][ty]>temp.step+1&&!flag[tx][ty])
			{
				node t;
				t.x=tx;
				t.y=ty;
				flag[tx][ty]=1;
				//printf("%d %d\n",tx,ty);
				t.step=temp.step+1;
				road.push(t);
			}
		}
	}
	return -1;
}
void initia()
{
	while(!fir.empty()) fir.pop();
	while(!road.empty()) road.pop();
}
int main()
{
	while(~scanf("%d%d%d",&n,&m,&speed)&&n)
	{
		initia();
		memset(flag,0,sizeof(flag));
		int i,j;
		char temp[105];
		int longth;
		for(i=0;i<n;i++)
		{
			scanf("%s",temp);
			for(j=0;j<m;j++)
			{
				if(temp[j]=='-') fire[i+1][j+1]=maxn;
				else if(temp[j]=='f')
				{
					//printf("%d %d\n",i+1,j+1);
					fire[i+1][j+1]=0;
					node t;
					t.x=i+1;
					t.y=j+1;
					fir.push(t);
				}
				else if(temp[j]=='s')
				{
					be.x=i+1;
					be.y=j+1;
					be.step=0;
					flag[i+1][j+1]=1;
					fire[i+1][j+1]=maxn;
				}
				else if(temp[j]=='t')
				{
					en.x=i+1;
					en.y=j+1;
					fire[i+1][j+1]=maxn;
				}
			}
		} 
		bfs_fire();
		longth=bfs_road();
		if(longth>0) printf("%d\n",longth);
		else printf("Impossible\n");
	}
}

Flip Game

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 51439 Accepted: 21712

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules: 

  1. Choose any one of the 16 pieces. 
  2. Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).


Consider the following position as an example: 

bwbw 
wwww 
bbwb 
bwwb 
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become: 

bwbw 
bwww 
wwwb 
wwwb 
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal. 

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

Source

Northeastern Europe 2000

又是一道状态压缩,4*4刚好16位。每个点的位数是:行数*4+列数而翻转即对这一位进行“异或”操作state^(1<<i)(state是当前的状态,i是棋子的序号),最终的状态要等于0或者65535

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>

using namespace std;
struct node{
	int state;
	int step;
	node(int state=0,int step=0):state(state),step(step){} 
};
int flag[70000];
void reversal(int &ste,int lot)
{
	int r=lot/4,c=lot%4;
	ste^=(0x1<<lot);
	if(r>=1)
	ste^=(0x1<<(lot-4));
	if(r<=2)
	ste^=(0x1<<(lot+4));
	if(c>=1)
	ste^=(0x1<<(lot-1));
	if(c<=2)
	ste^=(0x1<<(lot+1));
}
queue<node> q;
int bfs(int s)
{
	node a(s,0);
	flag[s]=1;
	q.push(a);
	while(!q.empty())
	{
		node fir=q.front();
		q.pop();
		if(fir.state==0||fir.state==65535) return fir.step;
		for(int i=0;i<16;i++)
		{
			node nxt=fir;
			reversal(nxt.state,i);
			if(!flag[nxt.state])
			{
				nxt.step++;
				q.push(nxt);
				flag[nxt.state]=1;
			}
		}
	}
	return -1;
}
char m[4][4];
int main()
{
	
	int beg=0;
	for(int i=0;i<4;i++)
	{
		scanf("%s",m[i]);
		for(int j=0;j<4;j++)
		{
			if(m[i][j]=='b')
			{
				beg^=(1<<(i*4+j));
			}
		}
	}
	int ans=bfs(beg);
	if(ans==-1) printf("Impossible\n");
	else printf("%d\n",ans);
	return 0;
}

 

转载于:https://www.cnblogs.com/fly-white/p/10092778.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值