题意是给一个给定一个范围刷颜色,然后又一范围刷另一种颜色(可能会覆盖之前的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替代了
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;
}