ural1147(Shaping Regions)矩形切割

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1147


题意:一个10000*10000的矩阵,初始颜色都为1,然后最多2500次涂色,每次涂色将一个矩形的面积涂成某个特定颜色,问涂完之后每种颜色最终的面积。


解法:倒序计算,矩形切割


代码:

/******************************************************
* @author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std;

#define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef long long LL;
const int Max=2510;
const int INF=1e9+7;

struct rec
{
    int x1,x2,y1,y2;
    int color;
} recs[Max];
int A,B;
int n;
int  getans(int x1,int x2,int y1,int y2,int p)
{
    while((p<=n)&&(x1>=recs[p].x2||x2<=recs[p].x1||y1>=recs[p].y2||y2<=recs[p].y1))
        p++;
    if(p>n)
        return (x2-x1)*(y2-y1);
    int ans=0;
    if(x1<recs[p].x1)
        ans+=getans(x1,recs[p].x1,y1,y2,p+1),x1=recs[p].x1;
    if(x2>recs[p].x2)
        ans+=getans(recs[p].x2,x2,y1,y2,p+1),x2=recs[p].x2;
    if(y2>recs[p].y2)
        ans+=getans(x1,x2,recs[p].y2,y2,p+1),y2=recs[p].y2;
    if(y1<recs[p].y1)
        ans+=getans(x1,x2,y1,recs[p].y1,p+1);
    return ans;
}
int ans[Max];
int main()
{
    while(~scanf("%d%d%d",&A,&B,&n))
    {
        memset(ans,0,sizeof ans);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d%d%d",&recs[i].x1,&recs[i].y1,&recs[i].x2,&recs[i].y2,&recs[i].color);
        }
        ans[1]=A*B;
        for(int i=n; i>=1; i--)
        {
            int tool=getans(recs[i].x1,recs[i].x2,recs[i].y1,recs[i].y2,i+1);
            ans[recs[i].color]+=tool;
            ans[1]-=tool;
        }
        for(int i=1; i<=2500; i++)
            if(ans[i])
                printf("%d %d\n",i,ans[i]);
    }
    return 0;
}
/*
20 20 3
2 2 18 18 2
0 8 19 19 3
8 0 10 19 4
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值