1092 - Tracking Bio-bots

The researchers at International Bio-bot Makers (IBM) have invented a new kind of Bio-bot, a robot with behavior mimicking biological organisms. The development of the new robot is at a primitive stage; they now resemble simple four-wheeled rovers. And like most modern robots, Bio-bots are not very mobile. Their weak motors and limited turning capability put considerable limitations on their movement, even in simple, relatively obstacle-free environments.

Currently the Bio-bots operate in a room which can be described as an m x n grid. A Bio-bot occupies a full square on this grid. The exit is in the northeast corner, and the room slopes down towards it, which means the Bio-bots are only capable of moving north or east at any time. Some squares in the room are also occupied by walls, which completely block the robot. Figure 1, which corresponds to the sample input, shows an example of such a room.

\epsfbox{p4787.eps}

Clearly, a Bio-bot located on square A is capable of leaving the room, while one at square B is trapped inside it, no matter what it does. Locations like B are called ``stuck squares." (Walls do not count as stuck squares.) Given the description of a room, your job is to count the total number of stuck squares in the room.

Input 

Input consists of multiple test cases, each describing one room. Each test case begins with a line containing three integers mn, and w (1$ \le$mn$ \le$106, 0$ \le$w$ \le$1000). These indicate that the room contains mrows, n columns, and w horizontal walls.

Each of the next w lines contains four integers x1y1x2y2, the coordinates of the squares delimiting one wall. All walls are aligned from west to east, so 0$ \le$x1$ \le$x2 < n and 0$ \le$y1 = y2 < m. Walls do not overlap each other. The southwest corner of the room has coordinates (0,0) and the northeast corner has coordinates(n - 1, m - 1).

The last test case is followed by a line containing three zeros.

Output 

For each test case, display one line of output containing the test case number followed by the number of stuck squares in the given room. Follow the format shown in the sample output.

Sample Input 

8 8 3 
1 6 3 6 
2 4 2 4 
4 2 7 2 
0 0 0

Sample Output 

Case 1: 8






#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int MAXN=2010;
struct Twall
{
	int x1,x2,y;
};
int n,m,w,n1,m1;
Twall a[MAXN];
int lx[MAXN*2];
long long ans;
bool f[MAXN];
bool g[MAXN];

void init()
{
	int i;
	ans=(long long) n*m;
	n1=0;
	for(i=1;i<=w;++i)
	{
		scanf("%ld %ld %ld %ld",&a[i].x1,&a[i].y,&a[i].x2,&a[i].y);
		++a[i].x2;
		ans-=a[i].x2-a[i].x1;
		lx[++n1]=a[i].x1;
		lx[++n1]=a[i].x2;
	}
	lx[++n1]=0;
	lx[++n1]=n;
}

void discrete(int a[],int &len)
{
	sort(a+1,a+1+len);
	int i,j=1;
	for(i=2;i<=len;++i)
		if(a[j]!=a[i])
			a[++j]=a[i];
	len=j;
}

int bin(int a[],int len,int k)
{
	int l=1;
	int r=len;
	int m;
	while(l<r)
	{
		m=(l+r)>>1;
		if(a[m]==k)
			return m;
		else if(a[m]>k)
			r=m-1;
		else
			l=m+1;
	}
	return -1;
}

bool cmp_Twall(Twall a,Twall b)
{
	if(a.y==b.y)
		return a.x2>b.x2;
	else
		a.y>b.y;
}

void deal_f(int k)
{
	int i;
	long long t=0;
	for(i=1;i<n1;++i)
		if(f[i])
			t+=lx[i+1]-lx[i];
	ans-=(long long )t*k;
}



void solve()
{
	discrete(lx,n1);
	int i,j;
	for(i=1;i<=w;++i)
	{
		a[i].x1=bin(lx,n1,a[i].x1);
		a[i].x2=bin(lx,n1,a[i].x2);
	}
	sort(a+1,a+w+1,cmp_Twall);
	int last=m;
	memset(f,0,sizeof(f));
	f[n1-1]=true;
	int st=1,ed;
	while(st<=w)
	{
		ed=st;
		while((ed<w)&&(a[ed+1].y==a[ed].y))
			++ed;
		if(a[st].y!=last-1)
		{
			for(i=n1-2;i>=1;--i)
				f[i]=f[i]||f[i+1];
			deal_f(last-a[st].y-1);
		}
		memset(g,true,sizeof(g));
		for(i=st;i<=ed;++i)
			for(j=a[i].x1;j<a[i].x2;++j)
				g[j]=false;
		f[n1-1]=f[n1-1]&&g[n1-1];
		for(i=n1-2;i>=1;--i)
			f[i]=g[i]&&(f[i]||f[i+1]);
		deal_f(1);
		last=a[st].y;
		st=ed+1;
	}
	for(i=n1-2;i>=1;--i)
		f[i]=f[i]||f[i+1];
	deal_f(last);
	printf("%lld\n",ans);
}

int main()
{
	int CASE=0;
	while((scanf("%ld %ld %ld",&m,&n,&w)!=EOF)&&(n||m))
	{
		init();
		printf("Case %ld: ",++CASE);
		solve();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值