Usaco Section 2.1 The Castle

本文通过解决USACO的城堡问题,介绍了Floodfill算法的应用。该算法用于分割地图上的不同房间,并计算每个房间的大小及最大可能的空间合并方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

题目:http://ace.delos.com/usacoprob2?a=eURSI1UXlof&S=castle

floodfill算法的典型应用!

 

/*

ID: lvxiaol3

PROG: castle

LANG: C

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <assert.h>

 

#define MAXDIM 50

#define MAXN 100

#define MAXCOLOR 100

#define MAXROOM (MAXDIM*MAXDIM)

 

enum 

{

Wwest = 1,

Wnorth = 2,

Weast = 4,

Wsouth = 8

};

 

typedef struct Square Square;

struct Square 

{

int wall;

int numbered;    //是否被遍历过

int room;

};

 

int wid, ht;

Square castle[MAXDIM][MAXDIM];

int roomsize[MAXROOM];

 

void number(int room, int x, int y)

{

int w;

 

if(castle[x][y].numbered) 

{

assert(castle[x][y].room == room);

return;

}

 

castle[x][y].numbered = 1;

castle[x][y].room = room;

roomsize[room]++;

 

w = castle[x][y].wall;

 

if(x > 0 && !(w & Wwest))     //只有x>0&&向西有空房间 number(room,x-1,y)       

number(room, x-1, y);

 

if(x+1 < wid && !(w & Weast))

number(room, x+1, y);

 

if(y > 0 && !(w & Wnorth))

number(room, x, y-1);

 

if(y+1 < ht && !(w & Wsouth))

number(room, x, y+1);

}

 

void main(void)

{

FILE *fin, *fout;

int x, y, w, nroom, bigroom;

int i, n, m, mx, my;

char mc;

 

fin = fopen("castle.in", "r");

fout = fopen("castle.out", "w");

assert(fin != NULL && fout != NULL);

 

fscanf(fin, "%d %d", &wid, &ht);

 

/* read in wall info */

for(y=0; y<ht; y++)

{

for(x=0; x<wid; x++) 

{

fscanf(fin, "%d", &w);

castle[x][y].wall = w;

}

}

 

/* number rooms */

nroom = 0;

for(y=0; y<ht; y++)

for(x=0; x<wid; x++)

if(!castle[x][y].numbered)

number(nroom++, x, y);

 

/* find biggest room */

bigroom = roomsize[0];

for(i=1; i<nroom; i++)

if(bigroom < roomsize[i])

bigroom = roomsize[i];

 

/* look at best that can come of removing an east or north wall */

 

//下面的策略是遍历了整个空间,来寻找最大的,并用m保存。

m = 0;

for(x=0; x<wid; x++)

{

for(y=ht-1; y>=0; y--) 

{

if(y > 0 && castle[x][y].room != castle[x][y-1].room) 

{

n = roomsize[castle[x][y].room] + roomsize[castle[x][y-1].room];

if(n > m)

{

m = n;

mx = x;

my = y;

mc = 'N';

}

}

if(x+1 < wid && castle[x][y].room != castle[x+1][y].room)

{

n = roomsize[castle[x][y].room] + roomsize[castle[x+1][y].room];

if(n > m) 

{

m = n;

mx = x;

my = y;

mc = 'E';

}

}

}

}

 

fprintf(fout, "%d/n", nroom);

fprintf(fout, "%d/n", bigroom);

fprintf(fout, "%d/n", m);

fprintf(fout, "%d %d %c/n", my+1, mx+1, mc);

exit(0);

}

 

//这个问题精彩的地方在于

/*nroom = 0;

for(y=0; y<ht; y++)

for(x=0; x<wid; x++)

if(!castle[x][y].numbered)

number(nroom++, x, y);

*/

//这一段的使用把整体的房间分割并标号。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值