hdu 1045 贪心求解

Hdu1045

题目大意:

有一个n行n列的地图,其中 '.' 代表空地,可以建造炮台,'x' 代表墙,建造规则是:每两个炮台之间必须有一堵墙,否者这两个炮台就会互相摧毁。现在输入一张这样的地图,要你计算最多可以建造多少炮台?

解题思路:

根据地图,得到一张新的数字地图,这张数字地图的构建方法是:

大小和原地图一样,

计算原地图的每一个 ' . ' 所在行列中有多少个 ‘ . ’,并将新图对应位置赋为该值。计算方法是:在每一行或每一列中走到底,或者遇到 ' x ' 结束。(可以包括本身也可以不包括本身,这里用不包括本身的方法)。

将原图中所有的 ' x ' 所在位置赋值为 无穷大(一个达不到的数即可,这里可以为 8 ,因为,最大为4行4列,这里计算又不包括本身,所以一个点所在的行列所有格子加起来最大也就是  6)。

按照这个方法可以得到一个新的地图:

在新图中贪心求解:(数字越小,证明在该点建造炮台影响到的点越少,可以建造的炮台也就越多)

找出第一排最小的数,判断是否小于 8  否 :  则下一行 。 是  :计数,然后将该点自己及其所影响到的不能再建造炮台的点赋值为无穷大。再找出最小的数,重复上述步骤,直到这一行没有小于8的数。

下一行:重复第一行的步骤,直到走完所有行结束。

代码如下

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main (){
    char **str;
	int **a,n,i,j,k,x,y,t,sum=0;
	while(scanf("%d",&n)&&n){
		getchar(); 
		str=(char **)malloc(sizeof(char *)*n);//动态申请二维字符数组  str[][];   用于存放字符地图 
		for(i=0;i<n;i++){
			str[i]=(char *)malloc(sizeof(char)*n);
		}
		a=(int **)malloc(sizeof(int *)*n);//动态申请二维整型数组   a[][];   用于存放数字地图 
		for(i=0;i<n;i++){
			a[i]=(int *)malloc(sizeof(int)*n);
		}
	for(i=0;i<n;i++){                     //录入字符地图. 
		for(j=0;j<n;j++)
			scanf("%c",&str[i][j]);
			getchar();
	}
	for(i=0;i<n;i++){    //预处理过程,根据输入的字符地图形成新的利于操作的数字地图 
		for(j=0;j<n;j++){
			t=0;
			if(str[i][j]=='.'){
				for(k=i-1;k>=0&&str[k][j]=='.';k--)//上 
				t++;
				for(k=i+1;k<n&&str[k][j]=='.';k++)//下 
				t++;
				for(k=j-1;k>=0&&str[i][k]=='.';k--)//左 
				t++;
				for(k=j+1;k<n&&str[i][k]=='.';k++)//右 
				t++;
				a[i][j]=t;
			}
			else
			a[i][j]=8;
		}
	} 
	for(i=0;i<n;i++){
		t=8;
		for(j=0;j<n;j++){
			if(a[i][j]<t){
				t=a[i][j];
				x=i;
				y=j;
			}
		}
		if(t!=8){
			sum++;
			i--;
			a[x][y]=8;
			for(k=x-1;k>=0&&a[k][y]!=8;k--)    //上 
			a[k][y]=8;
			for(k=x+1;k<n&&a[k][y]!=8;k++)    //下 
			a[k][y]=8;
			for(k=y-1;k>=0&&a[x][k]!=8;k--)   //左 
			a[x][k]=8;
			for(k=y+1;k<n&&a[x][k]!=8;k++)    //右 
			a[x][k]=8;
		}
	}
	printf("%d\n",sum);
	sum=0;
}
	return 0;
	} 
	/*	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			printf("%d",a[i][j]);
		}
		printf("\n");
	}*/

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值