USACO 5.5.1矩形と周長を求める
3658 ワード
まず矩形を一連の線分に離散化し,ここでは横辺を例に,横辺を離散化した後,縦座標で並べ替え,縦座標が同じときに始辺が前になる.次に、1つの線分について、対応する区間のpos[j]++は、pos[j]が0-」1または1->0である場合、ans++である.このプロセスでは、次のコードで線分ツリーを使用して最適化することもできます.
/*
ID: m1500293
LANG: C++
PROG: picture
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int N;
int pos[20000+100];
int m = 10000;
struct edge
{
int x, y, f;
int flog;
bool operator < (const edge& r) const
{
if(f == r.f)
{
return flog>r.flog;
}
return f < r.f;
}
}e[2][10000+10];
int solve(int o)
{
memset(pos, 0, sizeof(pos));
sort(e[o], e[o]+2*N);
int res = 0;
for(int i=0; i<2*N; i++)
for(int j=e[o][i].x; j<e[o][i].y; j++)
{
pos[j+m] += e[o][i].flog;
if(pos[j+m]==0 && e[o][i].flog<0)
res++;
if(pos[j+m]==1 && e[o][i].flog>0)
res++;
}
return res;
}
int main()
{
freopen("picture.in", "r", stdin);
freopen("picture.out", "w", stdout);
scanf("%d", &N);
for(int i=0; i<N; i++)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
e[0][i*2] = (edge){x1, x2, y1, 1};
e[0][i*2+1] = (edge) {x1, x2, y2, -1};
e[1][i*2] = (edge) {y1, y2, x1, 1};
e[1][i*2+1] = (edge) {y1, y2, x2, -1};
}
int ans1 = solve(0);
int ans2 = solve(1);
printf("%d
", ans1+ans2);
return 0;
}