hdu1543( 大范围刷新区间颜色)

题意是给一个给定一个范围刷颜色,然后又一范围刷另一种颜色(可能会覆盖之前的color),问最后有几种颜色和分别的面积


肯定立刻会想到二维区间跟新,然而这道题总范围10000*10000,内存超限


所以换一种记录方式,将每一个范围起末坐标记录下来并放到两个数组中(横坐标纵坐标分开),排序

然后遍历每一个范围,对于这个范围的起末横纵坐标找到在XY中对应的标号,然后

for(int y=x1;y<x2;y++)

    for(int k=y1;k<y2;k++)

           etc[y][k]=a[i].c;

这样赋值的就只是标号了,有什么好处呢。。省内存啊,例如给一个范围的横坐标分别是3,300,若中间没有其他范围覆盖的话,那这个范围就是用标号1,2替代了


之后把标号遍历赋值color

for(int i=0;i<cx;i++)

      for(int j=0;j<cy;j++)

          if(etc[i][j])

              color[etc[i][j]]+=(X[i+1]-X[i])*(Y[j+1]-Y[j]);


代码:

//

//  main.cpp

//  paint

//

//  Created by Mr.Xue on 17/7/25.

//  Copyright © 2017 Mr.Xue. All rights reserved.

//


#include <stdlib.h>

#include <string.h>

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <time.h>

#include <stack>

#include <queue>

#include <map>

#include <set>

#include <vector>

#include <string>

#include <iostream>

#include <algorithm>

using namespace std;


#define ull unsigned __int64

#define ll __int64

//#define ull unsigned long long

//#define ll long long

#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

#define middle (l+r)>>1

#define MOD 1000000007

#define esp (1e-4)

const int INF=0x3F3F3F3F;

using namespace std;


int color[105],X[202],Y[202],etc[202][202];

struct node

{

    int x1,x2,y1,y2,c;

    void write()

    {

        scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&c);

        if(x1>x2)

            swap(x1,x2);

        if(y1>y2)

            swap(y1,y2);


    }

}a[202];

int bs(int key,int n,int t[])

{

    int l=0,r=n-1;

    while(l<=r)

    {

        int mid=(l+r)/2;

        if(t[mid]==key)

            return mid;

        if(t[mid]<key)

            l=mid+1;

        else

            r=mid-1;

    }

    return -1;

}

int main()

{

    int H,W,n,m,cx,cy;

    int x1,x2,y1,y2;

    int num=1,sum;

    while(~scanf("%d %d",&H,&W))

    {

        if(H==0&&W==0)

            break;

        scanf("%d",&n);

        memset(etc,0,sizeof(etc));

        memset(color,0,sizeof(color));

        sum=0;

        m=0;

        for(int i=0;i<n;i++)

        {

            a[i].write();

            X[m]=a[i].x1;

            Y[m++]=a[i].y1;

            X[m]=a[i].x2;

            Y[m++]=a[i].y2;

        }

        sort(X,X+m);

        sort(Y,Y+m);

        cx=1;

        cy=1;

        for(int i=1;i<m;i++)

        {

            if(X[i]!=X[i-1])

                X[cx++]=X[i];

            if(Y[i]!=Y[i-1])

                Y[cy++]=Y[i];

        }

        for(int i=0;i<n;i++)

        {

            x1=bs(a[i].x1,cx,X);

            x2=bs(a[i].x2,cx,X);

            y1=bs(a[i].y1,cy,Y);

            y2=bs(a[i].y2,cy,Y);

            for(int y=x1;y<x2;y++)

                for(int k=y1;k<y2;k++)

                    etc[y][k]=a[i].c;

        }

        for(int i=0;i<cx;i++)

            for(int j=0;j<cy;j++)

                if(etc[i][j])

                    color[etc[i][j]]+=(X[i+1]-X[i])*(Y[j+1]-Y[j]);

        if(num!=1)

            printf("\n");

        printf("Case %d:\n",num);

        for(int i=1;i<102;i++)

        {

            if(color[i])

            {

                sum++;

                printf("%d %d\n",i,color[i]);

            }

               

        }

        if(sum==1)

            printf("There is %d color left on the wall.\n",sum);

        else

            printf("There are %d colors left on the wall.\n",sum);

        num++;

    }

    return 0;

}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值