降雨量java_P4273 [NOI2004] 降雨量

这篇博客介绍了一个利用计算几何解决NOI2004降雨量问题的方法。通过将马路竖立,计算扫过的面积来确定遮挡的水量,然后采用数据结构和算法进行高效计算。主要涉及C++编程,包括结构体定义、排序、并查集等技术。
摘要由CSDN通过智能技术生成

把马路竖起来,横轴是时间

那么显然扫过的面积就是遮挡的水量

之后就是计算几何的事了

#include

#include

#include

#include

#include

using namespace std;

int n,k;

int xx[505],yy[505];

int x,y;

struct b{

int f;

int t;

double l;

} ed[2500];

int fa[100001];

int bl[2500];

struct re{

int lx,rx,uy,dy;

}rec[2500];

re tem;

re recc[5];

int find(int x){

return fa[x]==x?x:fa[x]=find(fa[x]);

}

int f(int x){

return x*x;

}

int di(int x,int y){

return f(xx[x]-xx[y])+f(yy[x]-yy[y]);

}

bool cmp(b x,b y){

return x.l

}

int p;

void add(int f,int to,int ne){

ed[++p].f=f;

ed[p].t=to;

ed[p].l=ne;

return ;

}

int cnt;

void com(int x,int y){

recc[y].lx=min(recc[y].lx,rec[x].lx);

recc[y].uy=min(recc[y].uy,rec[x].uy);

recc[y].rx=max(recc[y].rx,rec[x].rx);

recc[y].dy=max(recc[y].dy,rec[x].dy);

}

void can(int x,int y,re tem){

//cnt--;

recc[y]=tem;

}

int Aimee;

int znx=0x3fffff;

int ss(){

Aimee=0;

for(int i=1;i<=cnt;++i){

Aimee+=(recc[i].rx-recc[i].lx)*(recc[i].dy-recc[i].uy);

}

return Aimee;

}

void endd(){

Aimee=0;

for(int i=1;i<=cnt;++i){

Aimee+=(recc[i].rx-recc[i].lx)*(recc[i].dy-recc[i].uy);

}

znx=min(znx,Aimee);

}

bool ch(int i,int xx,int yy){

return (xx<=recc[i].rx&&xx>=recc[i].lx&&recc[i].dy>=yy&&recc[i].uy<=yy);

}

bool che(int x,int xx,int yy){

for(int i=1;i<=cnt;++i){

if(i==x)

continue;

if(ch(x,recc[i].lx,recc[i].dy)||

ch(x,recc[i].lx,recc[i].uy)||

ch(x,recc[i].rx,recc[i].dy)||

ch(x,recc[i].rx,recc[i].uy))

return 0;

}

return 1;

}

void kr(int i,int s){

if(s>znx){

return ;

}

if(i==n+1){

if(cnt==k)

znx=s;

return ;

}

if(cnt

re tem=recc[cnt+1];

cnt++;

recc[cnt]=rec[i];

if(che(cnt,rec[i].lx,rec[i].dy))

kr(i+1,ss());

recc[cnt]=tem;

cnt--;

}

for(int j=1;j<=cnt;++j){

re tem=recc[j];

com(i,j);

if(che(j,rec[i].lx,rec[i].dy))

kr(i+1,ss());

can(i,j,tem);

}

}

int main(){

scanf("%d%d",&n,&k);

for(int i=1;i<=n;++i){

scanf("%d%d",&x,&y);

rec[i].lx=rec[i].rx=x;

rec[i].dy=rec[i].uy=y;

}

kr(1,0);

cout<

return 0;

}

```

```

`那么显然扫过的面积就是遮挡的水量

之后就是计算几何的事了

````cpp

#include

#include

#include

#include

#include

using namespace std;

int n,k;

int xx[505],yy[505];

int x,y;

struct b{

int f;

int t;

double l;

} ed[2500];

int fa[100001];

int bl[2500];

struct re{

int lx,rx,uy,dy;

}rec[2500];

re tem;

re recc[5];

int find(int x){

return fa[x]==x?x:fa[x]=find(fa[x]);

}

int f(int x){

return x*x;

}

int di(int x,int y){

return f(xx[x]-xx[y])+f(yy[x]-yy[y]);

}

bool cmp(b x,b y){

return x.l

}

int p;

void add(int f,int to,int ne){

ed[++p].f=f;

ed[p].t=to;

ed[p].l=ne;

return ;

}

int cnt;

void com(int x,int y){

recc[y].lx=min(recc[y].lx,rec[x].lx);

recc[y].uy=min(recc[y].uy,rec[x].uy);

recc[y].rx=max(recc[y].rx,rec[x].rx);

recc[y].dy=max(recc[y].dy,rec[x].dy);

}

void can(int x,int y,re tem){

//cnt--;

recc[y]=tem;

}

int Aimee;

int znx=0x3fffff;

int ss(){

Aimee=0;

for(int i=1;i<=cnt;++i){

Aimee+=(recc[i].rx-recc[i].lx)*(recc[i].dy-recc[i].uy);

}

return Aimee;

}

void endd(){

Aimee=0;

for(int i=1;i<=cnt;++i){

Aimee+=(recc[i].rx-recc[i].lx)*(recc[i].dy-recc[i].uy);

}

znx=min(znx,Aimee);

}

bool ch(int i,int xx,int yy){

return (xx<=recc[i].rx&&xx>=recc[i].lx&&recc[i].dy>=yy&&recc[i].uy<=yy);

}

bool che(int x,int xx,int yy){

for(int i=1;i<=cnt;++i){

if(i==x)

continue;

if(ch(x,recc[i].lx,recc[i].dy)||

ch(x,recc[i].lx,recc[i].uy)||

ch(x,recc[i].rx,recc[i].dy)||

ch(x,recc[i].rx,recc[i].uy))

return 0;

}

return 1;

}

void kr(int i,int s){

if(s>znx){

return ;

}

if(i==n+1){

if(cnt==k)

znx=s;

return ;

}

if(cnt

re tem=recc[cnt+1];

cnt++;

recc[cnt]=rec[i];

if(che(cnt,rec[i].lx,rec[i].dy))

kr(i+1,ss());

recc[cnt]=tem;

cnt--;

}

for(int j=1;j<=cnt;++j){

re tem=recc[j];

com(i,j);

if(che(j,rec[i].lx,rec[i].dy))

kr(i+1,ss());

can(i,j,tem);

}

}

int main(){

scanf("%d%d",&n,&k);

for(int i=1;i<=n;++i){

scanf("%d%d",&x,&y);

rec[i].lx=rec[i].rx=x;

rec[i].dy=rec[i].uy=y;

}

kr(1,0);

cout<

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值