51nod 1278
来源:互联网 发布:无线鼠标品牌知乎 编辑:程序博客网 时间:2024/06/08 02:22
题目:fffffffffffff
平面上有N个圆,他们的圆心都在X轴上,给出所有圆的圆心和半径,求有多少对圆是相离的。
例如:4个圆分别位于1, 2, 3, 4的位置,半径分别为1, 1, 2, 1,那么{1, 2}, {1, 3} {2, 3} {2, 4} {3, 4}这5对都有交点,只有{1, 4}是相离的。
Input
第1行:一个数N,表示圆的数量(1 <= N <= 50000)第2 - N + 1行:每行2个数P, R中间用空格分隔,P表示圆心的位置,R表示圆的半径(1 <= P, R <= 10^9)
Output
输出共有多少对相离的圆。
Input 示例
41 12 13 24 1
Output 示例
1
题目分析:
/**
*方法一
*将圆分为左右短点,用线段表示,现在就变形为了线段相交问题
*左端点left=c-r,右端点right=c+r,按左端点升序排序,相等的话
按右端点升序排序,然或进行扫描,对于每一条线段i,当以后的某一条
*线段j的左端点大于i的右端点,则以后的所有线段与其(i)相离
*时间复杂度为O(nlog(n)+n^2)
*此题的数据是50000,正常的O(n*n)的时间肯定会超时
*现在我们可以考虑改变步长的方法优化算法(只能降低系数,但有时确实很好),
*我在查询的时候优化,另步长为100,如果当前的j满足条件,则最先满足
*条件的j一定在j之前的100个以内,只需要在查询j的前100个即可,
*时间复杂度O(n*log(n)+n*(n/100+100));对于本题将你n^2的系数降低了尽100倍
*************************************************************************
*方法二 感谢Dava
*把所有圆的起点和终点放在一个数组中,按大小排序(圆的左右短点表示)
*如果某个圆的起点与另一个圆终点大小相等,则把起点排在前面
*定义结构体
*struct{
* long long d;//线段的节点
* int tmp;//标记起点(0)和终点(1),
*}
*记录所有的起点和终点直接快排,
*令num=圆的个数,遇到起点num--,遇到终点sum+=num
*/
方法一:
#include<iostream> #include<string> #include<algorithm> using namespace std; struct node{ int left,right; }; node p[50005]; int cmp(node a,node b){ if(a.left<b.left) return 1; else if(a.left==b.left&&a.right<b.right) return 1; return 0; } int main() { int c,r,n; while(cin>>n){ for(int i=0;i<n;i++){ cin>>c>>r; p[i].left=c-r; p[i].right=c+r; } sort(p,p+n,cmp); int i,j,sum=0,k; for(i=0;i<n;i++){ for(j=i+100;j<n;j+=100){//步长为100 if(p[j].left>p[i].right) break; } if(j>n) j=n; for(k=j-1;k>0&&k>j-101;k--){//扫描之间100个元素 if(p[k].left<=p[i].right){ sum+=n-(k+1); break; } } } cout<<sum<<endl; } return 0; }
方法二:
#include<iostream> #include<algorithm> using namespace std; struct node{ long long d;//线段的节点 int flag;//标记起点(0)和终点(1), }p[100005]; int cmp(node a,node b){ if(a.d<b.d) return 1; else if(a.d==b.d&&a.flag==0) return 1; return 0; } int main() { int c,r,n; while(cin>>n){ int k=0; for(int i=0;i<n;i++){ cin>>c>>r; p[k].d=c-r; p[k++].flag=0;//起点 p[k].d=c+r; p[k++].flag=1;//终点 } //cout<<k<<endl; sort(p,p+k,cmp); int sum=0,num=n; for(int i=0;i<k;i++){ //cout<<p[i].d<<" "<<p[i].flag<<endl; if(p[i].flag==0) num--; else if(p[i].flag==1) sum+=num; } cout<<sum<<endl; } return 0; }
0 0
- 51nod 1278
- 51nod 1278【贪心】
- 【51Nod】1278
- 51nod 1278
- 51Nod
- 51Nod
- 51nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 51Nod
- 前端记住密码功能
- Installation failed with message INSTALL_FAILED_NO_MATCHING_ABIS.
- oracle根据逗号分割字符串
- 10本Java网站开发必看书籍,大神级别必修书籍,吐血推荐!!!
- HDFS
- 51nod 1278
- SSH框架依赖分析
- add jars和add external jars有什么区别?
- php+jquery+ajax+json的一个最简单实例
- Servlet之浏览器页面出现中文乱码问题
- CSU~1328: 近似回文词(模拟)
- 感知机(perceptron)算法与MATLAB实现
- python2,python3子类调用父类初始化函数的方法和注意事项
- 点击按钮,div发生各种样式变化