HDU4414 Finding crosses(AC)

Finding crosses

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)

Description
The Nazca Lines are a series of ancient geoglyphs located in the Nazca Desert in southern Peru. They were designated as a UNESCO World Heritage Site in 1994. The high, arid plateau stretches more than 80 kilometres (50 mi) between the towns of Nazca and Palpa on the Pampas de Jumana about 400 km south of Lima. Although some local geoglyphs resemble Paracas motifs, scholars believe the Nazca Lines were created by the Nazca culture between 400 and 650 AD.[1] The hundreds of individual figures range in complexity from simple lines to stylized hummingbirds, spiders, monkeys, fish, sharks, orcas, llamas, and lizards.
Above is the description of Nazca Lines from Wikipedia. Recently scientists found out that those lines form many crosses. Do those crosses have something to do with the Christian religion? Scientists are curious about this. But at first, they want to figure out how many crosses are there. So they took a huge picture of Nazca area from the satellite, and they need you to write a program to count the crosses in the picture.

To simplify the problem, we assume that the picture is an N*N matrix made up of 'o' and '#', and some '#' can form a cross. Here we call three or more consecutive '#' (horizontal or vertical) as a "segment".
The definition of a cross of width M is like this:
1) It's made up of a horizontal segment of length M and a vertical segment of length M.
2) The horizontal segment and the vertical segment overlap at their centers.
3) A cross must not have any adjacent '#'.
4) A cross's width is definitely odd and at least 3, so the above  mentioned "centers" can't be ambiguous.
For example, there is a cross of width 3 in figure 1 and there are no cross in figure 2 ,3 and 4.


You may think you find a cross in the top 3 lines in figure 2.But it's not true because the cross you find has a adjacent '#' in the 4th line, so it can't be called a "cross". There is no cross in figure 3 and figure 4 because of the same reason.

Input
There are several test cases.
In each test case:
The First line is a integer N, meaning that the picture is a N * N matrix ( 3<=N<=50) .
Next N line is the matrix.
The input end with N = 0


Output
For each test case, output the number of crosses you find in a line.


Sample Input
4
oo#o
o###
oo#o
ooo#
4
oo#o
o###
oo#o
oo#o
5
oo#oo
oo#oo
#####
oo#oo
oo##o
6
ooo#oo
ooo##o
o#####
ooo#oo
ooo#oo
oooooo
0


Sample Output
1
0
0

0


//AC

#define _CRT_SECURE_NO_WARNINGS

#include 

#define MAXN 55

char matrix[MAXN][MAXN];
int visit[MAXN][MAXN];
int N = 0;
int dir[4][2] = { { -1, 0 }, {1,0}, {0,1}, {0,-1} };

void init()
{
	int i = 0;
	int j = 0;
	for (i = 0; i < MAXN;i++)
	{
		for (j = 0; j < MAXN; j++)
		{
			matrix[i][j] = '\0';
			visit[i][j]  = 0;
		}
	}

	return ;
}

int findnum(int x, int y, int ops)
{
	int num = 0;
	int index = 1;
	int x1 = 0;
	int y1 = 0;
	switch (ops)
	{
		//往上找,就是横坐标变小
		case 1:
		{
			while (1)
			{
				x1 = x - index;
				y1 = y;
				if ((x1<1) || (x1>N) || (y1<0) || (y1>=N)) return num;
				if ('o' == matrix[x1][y1])  return num;
				//找两边有没有#
				if ((x1 >= 1) && (x1 <= N) && ((y1-1) >= 0) && ((y1-1) < N))
				{
					if ('#' == matrix[x1][y1 - 1]) return num;
				}

				if ((x1 >= 1) && (x1 <= N) && ((y1 + 1) >= 0) && ((y1 + 1) < N))
				{
					if ('#' == matrix[x1][y1 + 1]) return num;
				}

				num += 1;
				index += 1;
			}
		}
		break;

		case 2:
		{
			while (1)
			{
				x1 = x + index;
				y1 = y;
				if ((x1<1) || (x1>N) || (y1<0) || (y1 >= N)) return num;
				if ('o' == matrix[x1][y1])  return num;
				//找两边有没有#
				if ((x1 >= 1) && (x1 <= N) && ((y1 - 1) >= 0) && ((y1 - 1) < N))
				{
					if ('#' == matrix[x1][y1 - 1]) return num;
				}

				if ((x1 >= 1) && (x1 <= N) && ((y1 + 1) >= 0) && ((y1 + 1) < N))
				{
					if ('#' == matrix[x1][y1 + 1]) return num;
				}

				num += 1;
				index += 1;
			}
		}
		break;

		case 3:
		{
			while (1)
			{
				x1 = x ;
				y1 = y - index;
				if ((x1<1) || (x1>N) || (y1<0) || (y1 >= N)) return num;
				if ('o' == matrix[x1][y1])  return num;
				//找两边有没有#
				if (((x1 - 1) >= 1) && ((x1 - 1) <= N) && (y1 >= 0) && (y1 < N))
				{
					if ('#' == matrix[x1-1][y1]) return num;
				}

				if (((x1 + 1) >= 1) && ((x1 + 1) <= N) && (y1 >= 0) && (y1 < N))
				{
					if ('#' == matrix[x1+1][y1]) return num;
				}

				num += 1;
				index += 1;
			}
		}
		break;

		case 4:
		{
			while (1)
			{
				x1 = x;
				y1 = y + index;
				if ((x1<1) || (x1>N) || (y1<0) || (y1 >= N)) return num;
				if ('o' == matrix[x1][y1])  return num;
				//找两边有没有#
				if (((x1 - 1) >= 1) && ((x1 - 1) <= N) && (y1 >= 0) && (y1 < N))
				{
					if ('#' == matrix[x1 - 1][y1]) return num;
				}

				if (((x1 + 1) >= 1) && ((x1 + 1) <= N) && (y1 >= 0) && (y1 < N))
				{
					if ('#' == matrix[x1 + 1][y1]) return num;
				}

				num += 1;
				index += 1;
			}
		}
		break;

		default:
		break;
	}

	return num;
}

int findcross()
{
	int ans = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	int num1 = 0;
	int num2 = 0;
	int num3 = 0;
	int num4 = 0;

	//找cross的中心,最少也要从第2行开始,第1列也不可能
	for (i = 2; i <= N;i++)
	{
		for (j = 1; j < N; j++)
		{
			if ('o' == matrix[i][j]) continue;
			if (1 == visit[i][j]) continue;
			//找四个方向是否有相同的个数的#,如果有,找有没有相邻的#
			//往上找,就是横坐标变小
			num1 = findnum(i, j, 1);

			if (0 == num1) continue;

			//向下找,横坐标变大
			num2 = findnum(i, j, 2);

			if (num1 != num2) continue;

			//向左找,纵坐标变小 
			num3 = findnum(i, j, 3);

			if (num1 != num3) continue;

			//向右找,纵坐标变大
			num4 = findnum(i, j, 4);

			if (num1 != num4) continue;

			//有十字,设置已用过的#,下次就不用了

			ans += 1;
		}
	}

	return ans;
}

int main()
{
	//寻找以这个点为中心找
	int i = 0;
	int ans = 0;
	freopen("input.txt","r",stdin);
	while (scanf("%d",&N) &&(0 != N))
	{
		init();
		for (i = 1; i <= N; i++)
		{
			scanf("%s", matrix[i]);
		}
		ans = findcross();
		printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(HDU4414 Finding crosses(AC))