vijos p1883 月光的魔法
来源:互联网 发布:gameloft的java小游戏 编辑:程序博客网 时间:2024/04/27 16:49
背景
影几欺哄了众生了
天以外——
月儿何曾圆缺
描述
有些东西就如同月光的魔法一般.
Luke是爱着vijos的.
他想为自己心爱的东西画些什么.
就画N个圆吧.
把它们的圆心都固定在x轴上.
圆与圆.
为了爱,两两不能相交.
为了爱,它们可以互相贴在一起.
内切或外切,都是允许的.
vijos的美丽,在于人心.
vijos的孩子们,一定能告诉大家:Luke画的圆究竟把平面分割成了多少块?
月光恬美地洒在大地上.
Luke知道,如果什么都不画,平面就只有一块.多美呢!
Luke知道,只画一个圆,平面就分成了两块.也很美呢!
但Luke还是要多画一些的,因为他真的深爱着vijos呢.
格式
输入格式
输入数据第一行:输出一个整数N,1<=N<=300,000.表示圆的个数.
之后N行,每一行有2个整数,x[i]和r[i]表示圆心固定在x[i]的位置,半径为r[i].
-1,000,000,000<=x[i]<=1,000,000,000
1<=r[i]<=1,000,000,000
所有圆都是唯一的,不会出现重叠.
输出格式
输出只有一行,要求输出平面被分割成了多少块.
样例1
样例输入1
21 3
5 1
样例输出1
3样例2
样例输入2[复制]
32 21 13 1
样例输出2[复制]
5
样例3
样例输入3[复制]
47 5-9 11
样例输出3[复制]
6
关于这道题,我确实花了不少功夫,这道题的关键在于所有的圆位置关系只有内切、外切、内含、外含四种关系,不存在两个圆相互交叉。所以理论上有n个圆,平面就被分成n+1个,之所以多是因为有些圆被其他几个圆分成了两个了,看懂这一点就成功了一点了。接下来就是代码问题了,我的思路就是先给圆排序,左端点优先,由小到大排。如果左端点相同半径大的在前面。这之后就请看代码吧,相关解释在代码里面,我觉得更清晰点。
记录信息
评测结果
编译成功
foo.c: In function 'result':
foo.c:32:15: warning: variable 'k' set but not used [-Wunused-but-set-variable]
{ int i,j,p,k,q,o;
^
测试数据 #0: Accepted, time = 0 ms, mem = 4944 KiB, score = 10
测试数据 #1: Accepted, time = 0 ms, mem = 4948 KiB, score = 10
测试数据 #2: Accepted, time = 0 ms, mem = 4948 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 4948 KiB, score = 10
测试数据 #4: Accepted, time = 15 ms, mem = 4948 KiB, score = 10
测试数据 #5: Accepted, time = 46 ms, mem = 4948 KiB, score = 10
测试数据 #6: Accepted, time = 62 ms, mem = 4948 KiB, score = 10
测试数据 #7: Accepted, time = 46 ms, mem = 4948 KiB, score = 10
测试数据 #8: Accepted, time = 62 ms, mem = 4944 KiB, score = 10
测试数据 #9: Accepted, time = 124 ms, mem = 4944 KiB, score = 10
Accepted, time = 355 ms, mem = 4948 KiB, score = 100
#include "stdio.h"#include "stdlib.h"struct yuan //构造一个结构体来盛放相关信息{ int xin; //记录圆心 int ban; //记录半径 int left; //记录左端点 int right; //记录右端点}a[300000]; /*1<=N<=300,000,所以构造一个盛300000元素的数组,在这说明一点,这个数组要在所有函数外面,不要放在主函 数里,否则会报错,这是因为这个数组占用空间太大,主函数里的数组最多好像只能开到千位,当然这是c(目前我只学了c ,c++刚了解),别的语言还不清楚*/void result(struct yuan a[],int n);int cmp(const void *a,const void *b){ struct yuan *p=(struct yuan *)a;struct yuan *q=(struct yuan *)b;if(p->left!=q->left) return (p->left)-(q->left);else return (q->xin)-(p->xin);}int main() { int N,i;while(scanf("%d",&N)!=EOF){ for(i=0;i<N;i++) { scanf("%d%d",&a[i].xin,&a[i].ban); a[i].left=a[i].xin-a[i].ban; a[i].right=a[i].xin+a[i].ban; } qsort(a,N,sizeof(a[0]),cmp);/*数组排序,如果是c++的话用sort会更方便也更为稳定,原因可以看看两个函数 写cmp函数的区别,一目了然*/ result(a,N);//这个用来寻找有几个圆被分成了两个} return 0; }void result(struct yuan a[],int n){ int i,j,p,k,q,o;int sum=n+1; //sum用来记录平面的个数,初始值为n+1,有几个圆被平分就加上几for(i=0;i<n-1;i++){ if(a[i].left!=a[i+1].left) //如果一个圆被平分,那么排序后这个圆的下一个圆左端点肯定相同,否则不被平分 continue; j=i+2;k=1;o=0; if(j>=n) break; while(a[i].right>=a[j].right)//如果一个圆被平分,那么平分它的圆肯定在它里面 { p=j-1; while(a[p].right>=a[j].right)//这是寻找第一个左端点不同且在a[p]圆外的圆 { j++; if(j>=n) break; } if(a[p].right!=a[j].left)//如果一个圆平分,那么平分它的圆应该是连续的 { k=0; break; } q=j; if((a[i].right==a[q].right)&&(a[q].left==a[p].right))//判断该圆是否符合被平分 { o=1; break; } j++; if(j>=n) break; } if(o) sum++;}printf("%d\n",sum);}
- vijos P1883月光的魔法
- vijos p1883 月光的魔法
- Vijos 1883 月光的魔法(栈)
- vijos1883 月光的魔法
- [Vijos]P1282 佳佳的魔法照片
- 【Vijos-P1285】佳佳的魔法药水-Dijkstra思想
- 【vijos】【树形dp】佳佳的魔法药水
- vijos 1417 魔法塔防
- 月光下的女孩
- 月光下的凤尾竹
- 王心凌的月光
- 月光石的识别
- 月光下的乡愁
- 月光下的凤尾竹
- 那时的月光
- 城里的月光
- 午夜的月光
- 月光
- linux基本语法
- TestFlight APP测试(IOS如何让上架前给其他人测试)
- 五大算法之(4)回溯
- UNICODE GBK UTF-8等文本编码
- 自学宝典:10个学习Android开发的网站推荐
- vijos p1883 月光的魔法
- object-c---图片动画
- Java内部窗体的实现
- 博士春节返乡笔记为何爆-风青杨
- android json解析
- Centos 6.5 下hadoop2.5.2的HA集群原理讲解以及详细配置(手动切换)
- zoj 1060 && poj 1094 Sorting It All Out
- 基于Python的行为驱动开发实战
- Twitter Bootstrup风格jQuery用户向导插件