您的位置:首页 > 编程语言 > C语言/C++

百炼-2815-城堡问题-C语言-递归算法

2017-08-07 19:54 337 查看
首先是一种比较直观的解法,虽然原理没问题,但实现的就不是很有技巧了。

/*************************************************
**文件名:百炼-2815
**Copyright (c) 2015-2025 OrdinaryCrazy
**创建人:OrdinaryCrazy
**日期:20170807
**描述:百炼-2815参考答案
**版本:1.0
**************************************************/
#include <stdio.h>
struct block
{
int east,west,north,south,flag;
}blocks[50][50];
int r,c,room,maxa;
/*************************************************
**函数名:room_count
**输入:i-方块纵坐标,j-方块横坐标
**输出:如果尚未占用,返回方块所在房间的面积
**功能:计算方块所在房间面积
**创建人:OrdinaryCrazy
**日期:20170807
**版本:1.0
**************************************************/
int room_count(int i,int j)
{
blocks[i][j].flag = 0;
int area = 1;
if(blocks[i][j].east && blocks[i][j + 1].flag)
{
blocks[i][j].east = blocks[i][j + 1].west = 0;
area += room_count(i,j + 1);
}
if(blocks[i][j].west && blocks[i][j - 1].flag)
{
blocks[i][j].west = blocks[i][j - 1].east = 0;
area += room_count(i,j - 1);
}
if(blocks[i][j].north && blocks[i - 1][j].flag)
{
blocks[i][j].north = blocks[i - 1][j].south = 0;
area += room_count(i - 1,j);
}
if(blocks[i][j].south && blocks[i + 1][j].flag)
{
blocks[i][j].south = blocks[i + 1][j].north = 0;
area += room_count(i + 1,j);
}
return area;
}
int main()
{
int i,j,tmp;
scanf("%d%d",&r,&c);
for(i = 0;i < r;i++)
{
for(j = 0;j < c;j++)
{
blocks[i][j].flag = 1;//1表示尚未经过,0表示已经经过
scanf("%d",&tmp);
switch(tmp)//0表示无法通行,1表示可以通行
{
case 0 :
blocks[i][j].east = blocks[i][j].north = blocks[i][j].west = blocks[i][j].south = 1;
break;

case 1 :
blocks[i][j].west = 0;
blocks[i][j].east = blocks[i][j].north = blocks[i][j].south = 1;
break;
case 2 :
blocks[i][j].north = 0;
blocks[i][j].east = blocks[i][j].west = blocks[i][j].south = 1;
break;
case 4 :
blocks[i][j].east = 0;
blocks[i][j].west = blocks[i][j].north = blocks[i][j].south = 1;
break;
case 8 :
beb3
blocks[i][j].south = 0;
blocks[i][j].east = blocks[i][j].north = blocks[i][j].west = 1;
break;

case 3 :
blocks[i][j].north = blocks[i][j].west = 0;
blocks[i][j].east = blocks[i][j].south = 1;
break;
case 5 :
blocks[i][j].east = blocks[i][j].west = 0;
blocks[i][j].north = blocks[i][j].south = 1;
break;
case 9 :
blocks[i][j].south = blocks[i][j].west = 0;
blocks[i][j].east = blocks[i][j].north = 1;
break;
case 6 :
blocks[i][j].north = blocks[i][j].east = 0;
blocks[i][j].west = blocks[i][j].south = 1;
break;
case 10 :
blocks[i][j].north = blocks[i][j].south = 0;
blocks[i][j].east = blocks[i][j].west = 1;
break;
case 12 :
blocks[i][j].east = blocks[i][j].south = 0;
blocks[i][j].north = blocks[i][j].west = 1;
break;

case 7 :
blocks[i][j].east = blocks[i][j].north = blocks[i][j].west = 0;
blocks[i][j].south = 1;
break;
case 11 :
blocks[i][j].south = blocks[i][j].north = blocks[i][j].west = 0;
blocks[i][j].east = 1;
break;
case 13 :
blocks[i][j].east = blocks[i][j].south = blocks[i][j].west = 0;
blocks[i][j].north = 1;
break;
case 14 :
blocks[i][j].east = blocks[i][j].north = blocks[i][j].south = 0;
blocks[i][j].west = 1;
break;

case 15 :
blocks[i][j].east = blocks[i][j].north = blocks[i][j].west = blocks[i][j].south = 0;
break;
}
}
}
for(i = 0;i < r;i++)
{
for(j = 0;j < c;j++)
{
if(blocks[i][j].flag)
{
room++;
tmp = room_count(i,j);
tmp > maxa ? maxa = tmp : 0;
}
}
}
printf("%d\n%d\n",room,maxa);
return 0;
}

其实稍微观察一下给的4个数字机会明白:用位运算是最好的,然后再要个临时面积变量和占用状态记录数组就行了,代码一下子就短了许多。

/*************************************************
**文件名:百炼-2815
**Copyright (c) 2015-2025 OrdinaryCrazy
**创建人:OrdinaryCrazy
**日期:20170807
**描述:百炼-2815参考答案
**版本:2.0
**************************************************/
#include <stdio.h>
int r,c,room,maxa,tmpa,blocks[50][50],occupied[50][50];
/*************************************************
**函数名:room_count
**输入:i-方块纵坐标,j-方块横坐标
**功能:将方块对应的占用数组元素标记为方块所在房间号,并将方块所在房间面积算出记录在tmpa中
**创建人:OrdinaryCrazy
**日期:20170807
**版本:2.0
**************************************************/
void room_count(int i,int j)
{
if(occupied[i][j]) return;
occupied[i][j] = room;
tmpa++;
if(!(blocks[i][j] & 1)) room_count(i,j - 1);
if(!(blocks[i][j] & 2)) room_count(i - 1,j);
if(!(blocks[i][j] & 4)) room_count(i,j + 1);
if(!(blocks[i][j] & 8)) room_count(i + 1,j);
}
int main()
{
int i,j;
scanf("%d%d",&r,&c);
for(i = 0;i < r;i++)
for(j = 0;j < c;j++)
scanf("%d",&blocks[i][j]);
for(i = 0;i < r;i++)
for(j = 0;j < c;j++)
if(!occupied[i][j])
{
tmpa = 0;
room++;
room_count(i,j);
tmpa > maxa ? maxa = tmpa : 0;
}
printf("%d\n%d\n",room,maxa);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: