列表

详情


NC15205. 白金元首与克劳德斯

描述

在xy-直角坐标平面的天空中,有n片四边平行于坐标轴的矩形云朵。每一片云由一个五元组(xi,yi,wi,hi,di)表示,其中(xi,yi)为云左下角顶点的坐标,wi表示云在x轴方向的宽度,hi表示云在y轴方向的长度,di∈{0,1}为云的移动方向(0为横向,1为纵向)。具体来说,满足di=0的云沿x轴正方向以每秒1长度单位的速率不断移动,而满足di=1的云沿y轴正方向以每秒1长度单位的速率不断移动。
元首发现,所有的云在此时没有重叠的面积。他将这个时刻记作时刻0。他想知道,对于(-∞,+∞)中的任意时刻和平面上的任意一个点,最多可以同时被多少片云覆盖。一个点在某时刻被一朵云覆盖当且仅当这个点位于该时刻云朵所处矩形的内部(不含边界)。
你需要编写程序帮助元首满足他的好奇心。

输入描述

输入的第一行包含一个正整数 T —— 数据的组数。接下来包含 T组数据,格式如下,数据间没有空行。
第 1 行:一个正整数 n —— 云朵的数量。
接下来 n 行:每行五个空格分隔的整数 xi,yi,wi,hi,d—— 描述一朵云在时刻 0的状态。

输出描述

对于每组数据输出一行 —— 在任意时刻,覆盖平面上任意一个点的云朵数目的最大值。

示例1

输入:

3
1
0 0 1 1 0
3
0 -10 10 10 1
10 0 10 10 1
-10 0 10 10 0
3
0 10 10 10 1
10 20 10 10 1
10 0 10 10 0

输出:

1
2
2

说明:

第 1 组数据中,任意时刻的任意一个点至多被惟一的一片云覆盖。
第 2 组数据中,下图从左至右分别示意时刻 0、时刻 4、时刻 11 的情形。

第 3 组数据中,时刻 0 对应第 2 组数据时刻 20 的情形。在该组数据中,(-20, 0) 内的时刻均有 2 片云覆盖同一个点。请注意考察范围 (-∞, +∞) 包含时刻 0 之前的时间段。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 904ms, 内存消耗: 6036K, 提交时间: 2021-01-29 21:59:13

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef struct n
{
	 int x,y,w,h;
	 int l,r;
};
int cmp(n x,n y)
{
	  return x.l<y.l;
}
n lef[maxn];
n up[maxn];
int leff=0;
int upp=0;
int main()
{
	int t;
	int x,y,w,h,d;
	int k;
	int q=0;
	cin>>t;
	for(int i=0;i<t;i++)
	{
		cin>>k;
		q=0;
		leff=0;
		upp=0;
		for(int j=0;j<k;j++)
		{
			 scanf("%d%d%d%d%d",&x,&y,&w,&h,&d);
			 if(d==0)
			  {
			  	 lef[leff]=(n){x,y,w,h,x+y,x+y+w+h};
			  	 leff++;
			  }
			  else if(d==1)
			  {
			  	 up[upp]=(n){x,y,w,h,x+y,x+y+w+h};
			  	 upp++;
			  }
		}
		sort(lef,lef+leff,cmp);
		sort(up,upp+up,cmp);
		for(int j=0,k=0;j<leff;j++)
		{
			
			 while(k<upp&&up[k].l<lef[j].l) k++;
			 if(k>=upp) break;
			 if(up[k].l<lef[j].r) 
			 {
			 	 q=1;
			 	 break;
			 }
		}
		
		for(int j=0,k=0;j<upp;j++)
		{
			
			 while(k<leff&&lef[k].l<up[j].l) k++;
			 if(k>=leff) break;
			 if(up[j].r>lef[k].l) 
			 {
			 	 q=1;
			 	 break;
			 }
		}
		if(q)
		   printf("2\n");
		else
		   printf("1\n");
	}
	
	
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 1076ms, 内存消耗: 2576K, 提交时间: 2020-07-04 09:57:03

#include <cstdio>
#include <algorithm>
int n, sum[2], T, X, Y, U, V, D, tot;
struct cyc
{
    int x, d, k;
} a[200010];
bool cmp(cyc a, cyc b) { return a.x < b.x || (a.x == b.x && a.k < b.k); }
int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        tot = 0;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d%d%d%d", &X, &Y, &U, &V, &D);
            a[++tot] = (cyc){X + Y, D, 1};
            //线段开始 +1
            a[++tot] = (cyc){X + Y + U + V, D, -1};
            //线段结束 -1
        }
        std::sort(a + 1, a + tot + 1, cmp);
        sum[0] = sum[1] = 0;
        int ans = 1;
        for (int i = 1; i <= tot; i++)
        {
            sum[a[i].d] += a[i].k;
            if (sum[0] && sum[1])
            {
                ans = 2;
                break;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

上一题