4.引水入城 (NOIP2010)复赛 提高组 试题四 解题代码

 

点击查看题目

#include <stdio.h>
#include <stdlib.h>

#define DEBUG

#ifndef DEBUG
#define N_MAX (500+1)
#define M_MAX (500+1)

#else
#define N_MAX (10+1)
#define M_MAX (10+1)
#endif

int g_IsAllSucceed = 0 ,g_iBuildCnt = 0,g_iCanNotBuild = 0;
int g_iHeight = 0,g_iWidth = 0;
int g_City[N_MAX][M_MAX],g_FlagOK[N_MAX][M_MAX] = {0};


void ReadFile()
{
	int i = 0,j = 0;
	FILE *fp = fopen("flow.in","rb");
	if (fp == NULL)
	{
		return;
	}
	fscanf(fp,"%d%d",&g_iHeight,&g_iWidth);
	for (i = 1; i<=g_iHeight ; i++)
	{
		for (j = 1; j<=g_iWidth ; j++)
		{
			fscanf(fp,"%d",&g_City[i][j]);
		}
	}

	fclose(fp);
}

void WriteFile()
{
	int i = 0;
	FILE *fp = fopen("flow.out","wb");
	if (fp == NULL)
	{
		return;
	}
	if (g_IsAllSucceed != 0)
	{
		fprintf(fp,"%d\r\n%d\r\n",g_IsAllSucceed,g_iBuildCnt);
	}
	else
	{
		fprintf(fp,"%d\r\n%d\r\n",g_IsAllSucceed,g_iCanNotBuild);
	}
	

	fclose(fp);
}

void BuildAnother(int N,int M)
{
	int i = N,j = M;
	g_FlagOK[i][j] = 1;
	if ((g_City[i][j] > g_City[i][j-1]) && (j-1 >= 1))
	{
		BuildAnother(i,j-1);//左边一个
	}
	if ((g_City[i][j] > g_City[i][j+1]) && (j+1 <= g_iWidth))
	{
		BuildAnother(i,j+1);//右边一个
	}
	if ((g_City[i][j] > g_City[i-1][j]) && (i-1 >= 1))
	{
		BuildAnother(i-1,j);//上边一个
	}
	if ((g_City[i][j] > g_City[i+1][j]) && (i+1 <= g_iHeight))
	{
		BuildAnother(i+1,j);//下边一个
	}
}

void BuildOne(int N,int M)
{
   g_iBuildCnt++;
   int i = N,j = M;
   g_FlagOK[i][j] = 1;
   if ((g_City[i][j] > g_City[i][j-1]) && (j-1 >0))
   {
	   BuildAnother(i,j-1);//左边一个
   }
   if ((g_City[i][j] > g_City[i][j+1]) && (j+1 <= g_iWidth))
   {
      BuildAnother(i,j+1);//右边一个
   }
   if ((g_City[i][j] > g_City[i+1][j]) && (i+1 <= g_iHeight))
   {
	   BuildAnother(i+1,j);//下边一个
   }
}

void CheckCanNotBuild()
{
	for (int i = 1; i <= g_iHeight ; i++)
	{
		for (int j = 1;j <= g_iWidth;j++)
		{
			if (g_FlagOK[i][j] == 0)
			{
				g_iCanNotBuild ++;
			}
		}
	}
}

int IsFinished()
{
	int iRet  = 1;
	for (int i = 1; i <= g_iHeight ; i++)
	{
		for (int j = 1;j <= g_iWidth;j++)
		{
			if (g_FlagOK[i][j] == 0)
			{
				iRet = 0;
				i = g_iHeight+1;//break All
				break;
			}
		}
	}
	return iRet;
}

int Flow()
{
	int iMaxHeight = 0;
	int iMaxj = 0;
	int iIsNoneToBuild = 1;
	do 
	{
		iIsNoneToBuild = 1;
		iMaxHeight     = 0;
		for (int j = 1; j <= g_iWidth;j++ )
		{
			if ((g_City[1][j] >iMaxHeight) && (g_FlagOK[1][j] == 0))
			{
				iMaxHeight  = g_City[1][j];
				iMaxj       = j;
				iIsNoneToBuild = 0;
			}
		}
		BuildOne(1,iMaxj);
    } while ((IsFinished() == 0) && (iIsNoneToBuild != 1));
	if (IsFinished() == 1)
	{
		return 1;
	}
	return 0;
}

int main(int argc, char* argv[])
{
	ReadFile();
	g_IsAllSucceed = Flow();
	if (g_IsAllSucceed == 0)
	{
		CheckCanNotBuild();
	}
	WriteFile();
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值