Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17464 | Accepted: 6654 |
Description
Input
The input file is terminated by a line containing a single 0. Don't process it.
Output
Output a blank line after each test case.
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
I met several bugs:
1. printf("%.2f", res); for double type instead of the setence printf("%.2lf", res); because for g++, %lf is not supported, so we must use %f for output and %lf for input.
2. Output a blank line after each test case.
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
using namespace std;
class Rec {
public:
double ltx, lty, rdx, rdy;
Rec(double x1 = 0, double y1 = 0, double x2 = 0, double y2 = 0): ltx(x1), lty(y1), rdx(x2), rdy(y2){
}
};
class Inte {
public:
double s, e;
Inte(double s1 = 0, double e1 = 0) : s(s1), e(e1) {
}
};
class cmp1 {
public:
bool operator()(const Inte& inte1, const Inte& inte2) const{
return inte1.s == inte2.s ? inte1.e < inte2.e : inte1.s < inte2.s;
}
};
class Solution{
public:
vector<Inte> merge(vector<Inte>& inte) {
vector<Inte> res;
if (inte.empty())
return res;
sort(inte.begin(), inte.end(), cmp1());
Inte cur(inte[0].s, inte[0].e);
int size = inte.size();
for (int i = 1; i < size; ++i) {
if (inte[i].s > cur.e) {
res.push_back(cur);
cur.s = inte[i].s, cur.e = inte[i].e;
}
else {
cur.s = min(cur.s, inte[i].s);
cur.e = max(cur.e, inte[i].e);
}
}
res.push_back(cur);
return res;
}
double calArea(vector<vector<Inte> >& inters, const vector<double>& xcoor) {
double res = 0;
int size = inters.size();
for (int i = 0; i < size; ++i) {
vector<Inte> cur = merge(inters[i]);
int cursize = cur.size();
for (int j = 0; j < cursize; ++j)
res += (cur[j].e - cur[j].s)*(xcoor[i+1]-xcoor[i]);
}
return res;
}
double calAllArea(const vector<Rec>& recs) {
int i, size = recs.size(), j, intesize;
vector<double> xcoor;
for (i = 0; i < size; ++i) {
xcoor.push_back(recs[i].ltx);
xcoor.push_back(recs[i].rdx);
}
sort(xcoor.begin(), xcoor.end());
xcoor.resize(unique(xcoor.begin(), xcoor.end()) - xcoor.begin());
intesize = xcoor.size() - 1;
vector<vector<Inte> > inters(intesize, vector<Inte>(0));
for (i = 0; i < size; ++i) {
int j1 = lower_bound(xcoor.begin(), xcoor.end(), recs[i].ltx) - xcoor.begin();
int j2 = upper_bound(xcoor.begin(), xcoor.end(), recs[i].rdx) - xcoor.begin();
for (j = j1; j <= j2 -2; ++j) {
inters[j].push_back( Inte(recs[i].rdy, recs[i].lty));
}
}
double res = calArea(inters, xcoor);
return res;
}
};
int main()
{
Solution s;
freopen("E://test.txt","r",stdin);
vector<Rec> recs;
int k, count = 0;
double x1, x2, y1, y2;
while (scanf("%d", &k) && k != 0) {
recs.resize(0);
printf("Test case #%d\n", ++count);
while (k--) {
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
recs.push_back(Rec(x1, y2, x2, y1));
}
double res = s.calAllArea(recs);
printf("Total explored area: %.2f\n\n", res);
}
return 0;
}
Another code using segment tree from :
http://blog.csdn.net/youngyangyang04/article/details/7787693
我的扫面线第一题,一开始看网上讲的都好抽象,最后还是研究别人代码整明白的,所以我要写一个直观的,哈哈哈!!希望大家都能看懂
如图虚线将整个图型分成三个矩形,我们现将每个点的x进行排序,也就是(10,15,20,25.5)
这样就知道矩形的长了,还差宽,然后我们就要开始扫描线啦
先每个点的y值离散话,因为我们要求的是映射在x轴的线段,然后建树,共有t哥点,样立t-1等于4
下面的线段树我每个离散花后的点对应的y值我都标记上了
将一号边加入线段,先加入一号边,二号边三号边四号边具体过程建议自己模拟一下
我每个线段树的点用s标记这条边被覆盖还是没被都盖,每条边的flag表示这天边是入度还是出度
注意啊!!我这个图x,y轴画反啦
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 300
struct Node{
double x;double y1;double y2;
int flag;
}node[N];
bool cmp(Node a,Node b){
return a.x-b.x<0.0000001;
}
double y[N];
struct node{
int l;int r;double ml;double mr;int s;double len;
}a[N*3];
void build(int i,int left,int right){
a[i].l=left;
a[i].r=right;
a[i].ml=y[left];
a[i].mr=y[right];
a[i].s=0;
a[i].len=0;
if(a[i].l+1==a[i].r){
return ;
}
int mid=(left+right)>>1;
build(i*2,left,mid);
build(i*2+1,mid,right);//建树时注意这里不是mid+1,因为做相减的时候如果mid+1这么建回到值左孩子的右边与有孩子的左边无法进行运算
}
void callen(int i){
if(a[i].s>0){//注意这里不是所有边都是左孩子的长度加上右孩子的长度,他存在一个覆盖问题
a[i].len=a[i].mr-a[i].ml;
}else if(a[i].r-a[i].l==1){
a[i].len=0;
}else{
a[i].len=a[i*2].len+a[i*2+1].len;
}
return ;
}
void updata(int i,Node b){
if(a[i].ml==b.y1&&a[i].mr==b.y2){
a[i].s+=b.flag;
callen(i);
return ;
}
if(b.y2<=a[i*2].mr) updata(i*2,b);
else if(b.y1>=a[i*2+1].ml) updata(i*2+1,b);
else{
Node temp=b;
temp.y2=a[i*2].mr;
updata(i*2,temp);
temp=b;
temp.y1=a[i*2+1].ml;
updata(i*2+1,temp);
}
callen(i);
return ;
}
int main(){
// freopen("in.txt","r",stdin);
int n,t,p=1,te;
double x1,x2,y1,y2;
while(scanf("%d",&n),n){
t=1;
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
node[t].x=x1;
node[t].y1=y1;
node[t].y2=y2;
node[t].flag=1;//入边
y[t++]=y1;
node[t].x=x2;
node[t].y1=y1;
node[t].y2=y2;
node[t].flag=-1;//出边
y[t++]=y2;
}
sort(node+1,node+t,cmp);
sort(y+1,y+t);
build(1,1,t-1);
updata(1,node[1]);
double sum=0;
for(int i=2;i<t;i++){
sum+=a[1].len*(node[i].x-node[i-1].x);
updata(1,node[i]);
}
printf("Test case #%d\n",p++);
printf("Total explored area: %.2lf\n\n",sum);
}
return 0;
}
Maybe for an interview:
#include <iostream>
class TNode {
public:
int l, r, s, len;
double ll, rr;
TNode *lc, *rc;
TNode(int l1 = 0, int r1 = 0, int s1 = 0, int len1 = 0, double ll1 = 0, double rr1 = 0): l(l1), r(r1), s(s1), ll(ll1), rr(rr1), len(len1), lc(NULL), rc(NULL){}
};
class Rec {
public:
double ldx, ldy, rtx, rty;
Rec(double ldx1 = 0, double ldy1 = 0, double rtx1 = 0, double rty1 = 0): ldx(ldx1), ldy(ldy1), rtx(rtx1), rty(rty1) {}
};
class Seg {
public:
double x, y1, y2;
int dir;
Seg(double x1 = 0, double yy1 = 0, double yy2 = 0, int dir1 = 0):x(x1), y1(yy1), y2(yy2), dir(dir1){}
};
class cmp {
public:
bool operator() (Seg& seg1, Seg& seg2) {
return seg1.x < seg2.x;
}
};
TNode* build(int l, int r, vector<int>& ysort) {
TNode* rt = new TNode(l, r, 0, 0, ysort[l], ysort[r]);
if (l + 1 >= r)
return rt;
int mid = (l + r) >> 1;
rt->lc = new Tnode(l, mid, 0, 0, ysort[l], ysort[mid]);
rt->rc = new Tnode(mid, r, 0, 0, ysort[mid], ysort[r]);
return rt;
}
void cal(TNode* rt) {
if (rt->s > 0)
rt->len += rt->rr-rt->ll;
else if (rt->l + 1 = rt->r)
rt->len = 0;
else
rt->len = rt->lc->len + rt->rc->len;
}
void update(TNode* rt, Seg &seg) {
if (rt->ll == seg.y1 && rt->rr == seg.y2) {
rt->s += seg.dir;
cal(rt);
}
else if (seg.y2 <= rt->lc->rr)
update(rt->lc, seg);
else if (seg.y1 >= rt->rc->ll)
update(rt->rc, seg);
else {
Seg tmp = seg;
tmp.y2 = rt->lc->rr;
update(rt->lc, tmp);
tmp = seg, tmp.y1 = rt->rc->ll;
update(rt->rc, tmp);
}
cal(rt);
}
int calArea(vector<Rec>& recs) {
vector<Seg> segs;
vector<int> ysort;
int i, size = recs.size(), l = 0, r = size-1;
for (i = 0; i < size; ++i) {
ysort.push_back(recs[i].ldx);
ysort.push_back(recs[i].rtx);
segs.push_back(Seg(recs[i].ldx, recs[i].ldy, recs[i].rty, 1));
segs.push_back(Seg(recs[i].rtx, recs[i].ldy, recs[i].rty, -1));
}
sort(ysort.begin(), ysort.end());
sort(segs.begin(), segs.end(), cmp());
TNode *rt = build(l, r, ysort);
update(rt, segs[0]);
int res = 0;
for (i = 1; i < size; ++i) {
res += rt->len * (segs[i].x - segs[i-1].x);
update(rt, segs[i]);
}
return res;
}