您的位置:首页 > 其它

【XJOI】【NOI考前模拟赛7】

2015-06-15 09:03 357 查看

DP+卡常数+高精度/ 计算几何+二分+判区间交/ 凸包

  首先感谢徐老师的慷慨,让蒟蒻有幸膜拜了学军的神题。祝NOI2015圆满成功

  同时膜拜碾压了蒟蒻的众神QAQ

填填填

  我的DP比较逗比……(当时看到其他大神有更加优秀的做法)

  f[i][j]表示前 i 个数,第一行填了 j 个的方案数,那么如果 i 并没有固定位置,f[i][j]=f[i-1][j]+f[i-1][j-1];即 i 这个数放在第一行或是第二行。。。(废话)

  如果 i 固定的位置是第一行(1,y),那么f[i]中只有f[i][y]=f[i-1][y-1];(这个数一定放在第一行)

  如果 i 固定的位置是第二行(2,y),那么f[i]中只有f[i][i-y]=f[i-1][i-y];(一定放在第二行)

  这个DP是会爆空间的,但是我们发现f[i]只跟f[i-1]有关,所以滚动数组优化一下就好了……(我一开始还在蛋疼高精度的数组开不下)

  我比较傻逼,不知道XJOI是不能用#ifndef ONLINE_JUDGE的,所以第一题没删文件操作……爆零滚粗了,删掉后是70分,两RE四TLE。

  然后开始了漫漫卡常之路……比如高精从int压9位改成long long压17位,高精加的过程用指针实现(Orz Davidlee1999)

  RE的那两个点是怎么回事呢?因为如果 i 固定的位置是第二行的时候,i-y可能会越界!(也就是无法得到一组合法解)那么这个时候我需要特判一下……

//XJOI test7 C
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=0,sign=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
return v*sign;
}
const int N=6010,INF=~0u>>2;
typedef long long LL;
/******************tamplate*********************/

struct Poi{
int x,y;
Poi(){}
Poi(int x,int y):x(x),y(y){}
void read(){x=getint(),y=getint();}
}p
,a
,st
,O(0,0);
typedef Poi Vec;
bool operator < (const Poi &a,const Poi &b){return a.x<b.x ||(a.x==b.x && a.y<b.y);}
Vec operator - (Poi a,Poi b){return Vec(a.x-b.x,a.y-b.y);}
double Cross(const Poi &a,const Poi &b){return (double)a.x*b.y-(double)a.y*b.x;}

int n,m,top,k;

void solve(){
top=0;
F(i,1,m){
while(top>1 && Cross(st[top]-st[top-1],a[i]-st[top-1])<=0) top--;
st[++top]=a[i];
}
int k=top;
D(i,m,1){
while(top>k && Cross(st[top]-st[top-1],a[i]-st[top-1])<=0) top--;
st[++top]=a[i];
}
double ans=0.0;
F(i,1,top-1) ans+=Cross(st[i]-O,st[i+1]-O)/2;
printf("%.1f\n",ans);
}

int main(){
k=getint(); n=getint();
F(i,1,n) p[i].read();
sort(p+1,p+n+1);
int q=getint();
F(i,1,q){
m=0;
int x1=getint(),x2=getint(),y1=getint(),y2=getint();
F(i,1,n) if (p[i].x>=x1 && p[i].x<=x2 && p[i].y>=y1 && p[i].y<=y2)
a[++m]=p[i];
solve();
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: