usaco window arear(递归求矩形覆盖面积)

这种算法挺厉害的。

画图很容易理解但是正确性很难证明。

学习了,。

这是到学校的第一份代码。

新的一学期又开始了。

/*
ID;jinbo wu
TASK:window
LANG:C++
*/
#include<bits/stdc++.h>
using namespace std;
struct node 
{
	int x0,y0,x,y;
	int num;
}w[77];
int k;
double ans;
int m;
void solve(int i,int x0,int y0,int x,int y)
{
	if(x0>=x||y0>=y)
	return ;
	for(;i<=75;i++)
	if(w[i].x0&&w[i].num>w[k].num) 
	break;
	if(i==76)
	{
	 m+=(y-y0)*(x-x0);
	 return ;
    }
	solve(i+1,x0,y0,min(x,w[i].x0),y);
	solve(i+1,max(x0,w[i].x),y0,x,y);
	solve(i+1,max(x0,w[i].x0),max(y0,w[i].y),min(x,w[i].x),y);
	solve(i+1,max(x0,w[i].x0),y0,min(x,w[i].x),min(y,w[i].y0));
	return ;
}
int main()
{
	freopen("window.in","r",stdin);
	freopen("window.out","w",stdout);
	char a,b,c;
	int minn=0;
	int maxn=0;
	while(~scanf("%c",&c))
	{
		if(c=='w')
		{
			scanf("%c%c",&a,&b);
			if(b>='0'&&b<='9')
			k=b-'0'+55;
			else if(b>='a'&&b<='z')
			k=b-'a'+28;
			else
			k=b-'A';
			scanf(",%d,%d,%d,%d",&w[k].x0,&w[k].y0,&w[k].x,&w[k].y);
			w[k].num=++maxn;
			if(w[k].x0>w[k].x)
			swap(w[k].x0,w[k].x);
			if(w[k].y0>w[k].y)
			swap(w[k].y0,w[k].y);
		}
		if(c=='b')
		{
			scanf("%c%c",&a,&b);
			if(b>='0'&&b<='9')
			k=b-'0'+55;
			else if(b>='a'&&b<='z')
			k=b-'a'+28;
			else
			k=b-'A';
			w[k].num=--minn;
		}
		if(c=='t')
		{
			scanf("%c%c",&a,&b);
			if(b>='0'&&b<='9')
			k=b-'0'+55;
			else if(b>='a'&&b<='z')
			k=b-'a'+28;
			else
			k=b-'A';
			w[k].num=++maxn; 
				
		}
		if(c=='d')
		{
		    scanf("%c%c",&a,&b);
			if(b>='0'&&b<='9')
			k=b-'0'+55;
			else if(b>='a'&&b<='z')
			k=b-'a'+28;
			else
			k=b-'A';
			w[k].x0=0;
		}
		if(c=='s')
		{
			m=0;
			scanf("%c%c",&a,&b);
			if(b>='0'&&b<='9')
			k=b-'0'+55;
			else if(b>='a'&&b<='z')
			k=b-'a'+28;
			else
			k=b-'A';
			ans=(w[k].x-w[k].x0)*(w[k].y-w[k].y0);
			solve(0,w[k].x0,w[k].y0,w[k].x,w[k].y);
			ans=m/ans*100;
			printf("%.3f\n",ans);
			
		}
	}
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值