华师一附中OI组
标题: P1302 可见矩形 [打印本页]
作者: 倚窗倾听风吹雨 时间: 2018-7-31 22:12
标题: P1302 可见矩形
https://www.luogu.org/problemnew/show/P1302
题目描述
给定平面上n个互不相交(指公共面积为零)的正方形,它们的顶点坐标均为整数。设坐标原点为O(0, 0)。对于任一正方形R,如果可以找到R的边上2个不同的点A和B,使三角形OAB的内部与其他正方形无公共点,则称正方形R是从O点可见的正方形。
对于给定的n个互不相交的正方形,计算从坐标原点O可见的正方形个数。
输入输出格式
输入格式:
输入文件的第一行是正方形个数n(1≤n≤1000)。
接下来n行中,每行有3个表示正方形的整数X,Y,L。其中,X和Y表示正方形的左下角顶点坐标,L表示边长,1≤X, Y, L≤10000。
输出格式:
输出文件仅有一行包含一个整数,表示从坐标原点O可见的正方形个数。
输入输出样例
输入样例#1:复制
3
2 6 4
1 4 1
2 4 1
输出样例#1:复制
3
作者: 倚窗倾听风吹雨 时间: 2018-7-31 22:13
- #include<iostream>
- #include<algorithm>
- using namespace std;
- int n,ans;
- struct square
- {
- int x,y,l,z;
- double zs,yx;
- }s[1010];
- bool cmp1(square x,square y)
- {
- return x.z<y.z;
- }
- bool cmp2(square a,square b)
- {
- return a.zs>=b.zs;
- }
- int main()
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- cin>>s[i].x>>s[i].y>>s[i].l;
- s[i].zs=float(s[i].y+s[i].l)/float(s[i].x);
- s[i].yx=float(s[i].y)/float(s[i].x+s[i].l);
- s[i].z=s[i].x+s[i].y+s[i].l;
- }
- sort(s+1,s+1+n,cmp1);
-
- for(int i=1; i<=n; i++)
- {
- sort(s+1,s+i,cmp2);
- bool flag=1;
- if(i>=2)
- {
- double a=s[1].zs;
- double b=s[1].yx;
- for(int j=1; j<i; j++)
- {
- if(s[j].zs>=b)
- {
- b=min(b,s[j].yx);
- }
- else
- {
- if(a>=s[i].zs && b<=s[i].yx)
- {
- flag=0;
- break;
- }
- a=s[j].zs;
- b=s[j].yx;
- }
- }
- if(a>=s[i].zs && b<=s[i].yx)
- flag=0;
- }
- if(flag)
- ans++;
- }
- cout<<ans<<endl;
- return 0;
- }
复制代码
作者: 吴语林 时间: 2018-8-1 09:30
线段树+离散化
- #include<cstring>
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- const int maxn=100005;
- bool hash[maxn];
- int cov[maxn<<4];
- double a[maxn*3];
- int cnt;
- struct node
- {
- double li,ri,z;
- }dian[maxn];
- int BinSea(double key,int n)
- {
- int l=0,r=n-1;
- while(l<=r)
- {
- int mid=(l+r)/2;
- if(a[mid]==key) return mid;
- else if(a[mid]<key) l=mid+1;
- else r=mid-1;
- }
- return -1;
- }
- void Pushdown(int p)
- {
- if(cov[p]!=-1){
- cov[p<<1]=cov[p<<1|1]=cov[p];
- cov[p]=-1;
- }
- }
- void Update(int p,int l,int r,int x,int y,int c)
- {
- if(x<=l&&y>=r)
- {
- cov[p]=c;
- return;
- }
- Pushdown(p);
- int mid=(l+r)>>1;
- if(x<=mid) Update(p<<1,l,mid,x,y,c);
- if(y>mid) Update(p<<1|1,mid+1,r,x,y,c);
- }
- void Query(int p,int l,int r)
- {
- if(cov[p]!=-1)
- {
- if(!hash[cov[p]])
- {
- cnt++;
- hash[cov[p]]=true;
- }
- return;
- }
- if(l==r) return;
- int mid=(l+r)>>1;
- Query(p<<1,l,mid);
- Query(p<<1|1,mid+1,r);
- }
- bool cmp(node x,node y)
- {
- return x.z>y.z;
- }
- int main()
- {
- int n,k;
- scanf("%d",&n);
- for(int i=0;i<n;i++)
- {
- double x,y,lon;
- scanf("%lf%lf%lf",&x,&y,&lon);
- dian[i].li=x/(y+lon),dian[i].ri=(x+lon)/y;
- dian[i].z=x+lon+y;
- a[k++]=dian[i].li;
- a[k++]=dian[i].ri;
- }
- sort(dian,dian+n,cmp);
- sort(a,a+k);
- int h=1;
- for(int i=1;i<k;i++)
- if(a[i]!=a[i-1])
- a[h++]=a[i];
- for(int i=h-1;i>0;i--)
- if((a[i]-a[i-1])>0.00000000001)
- a[h++]=a[i-1]+(a[i]-a[i-1])/2;
- sort(a,a+h);
- memset(cov,-1,sizeof(cov));
- for(int i=0;i<n;i++)
- {
- int l=BinSea(dian[i].li,h);
- int r=BinSea(dian[i].ri,h);
- Update(1,0,h-1,l,r,i);
- }
- cnt=0;
- memset(hash,false,sizeof(hash));
- Query(1,0,h-1);
- printf("%d\n",cnt);
- return 0;
- }
复制代码
作者: admin 时间: 2018-8-1 15:44
两位做的很认真!方法也是可行的,大家学习下
欢迎光临 华师一附中OI组 (http://hsyit.cn/) |
Powered by Discuz! X3.2 |