51NOD 1467 旋转绳 二分查找 模拟
2016-03-19 15:34
218 查看
1467 旋转绳题目来源: CodeForces基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注平面上有n个钉子,他们从1到n编号,第i个钉子的坐标是 (xi, 0)。然后我们我们把一个长度为L,带重物的绳子系到第i个钉子上(那么重物所在的坐标是(xi, -L))。然后用力将重物向右推,开始逆时针旋转。同时,如果旋转的过程中碰到其它的钉子,就会绕着那个钉子旋转。假设每个钉子都很细,重物绕着它旋转时,不影响到绳子的长度。更一般的,如果绳子碰到多个钉子,那么它会绕着最远的那个钉子转。特殊的,如果绳子的末端碰到了一个钉子,那么也会绕着那个钉子以长度为0的绳子在转。经过一段时间之后,重物就会一直绕着某个钉子转。现在有m个查询,每个查询给出初始的绳子长度以及挂在哪个钉子下旋转,请找出重物最终会绕哪个钉子旋转。样例解释:Input
单组测试数据。 第一行包含两个整数n 和 m (1 ≤ n, m ≤ 2*10^5),表示钉子的数目以及查询的数目。 接下来一行包含n个整数 x1, x2, ..., xn ( -10^9 ≤ xi ≤ 10^9),表示每个钉子的坐标。保证输入的钉子的坐标两两不相同。 接下来m行给出查询。每行给出ai (1 ≤ ai ≤ n) 和 li(1 ≤ li ≤ 10^9),表示该查询的重物挂在第ai个钉子上,绳子长度是li。Output
输出m行,第i行输出第i个查询的重物最终绕着哪个钉子转。
二分查找钉子然后加了点优化..
#include<iostream>#include<algorithm>#include<stdio.h>using namespace std;int ok(long long x);struct node{long long data;int id;};bool cmp(node x,node y){return x.data<y.data;}node s[200003];long long s1[200003]={0};int n=0,m=0;int jilv[3]={0};int t=0; int main(){while(scanf("%d%d",&n,&m)!=EOF){for(int i=1;i<=n;i++){scanf("%lld",&s[i].data);s[i].id=i;s1[i]=s[i].data;}sort(s+1,s+n+1,cmp);t=0;while(m--)4000{int x=0,r=0;t=0;cin>>x>>r;x=ok(s1[x]);int end=0;int sum=0;jilv[t++]=x;if(s[x].data+r<s[x+1].data||x==n) sum++; while(1) { int y=0; if(sum%2==0) { y=ok(s[x].data+r); if(s[x].data+r==s[y].data) { end=y; break; } else if(s[x].data==s[y].data) { end=y; break; } else { r=r-(s[y].data-s[x].data); x=y; } sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++;}else{r=r-p*R;t=1;} } else { jilv[0]=jilv[1]; jilv[1]=x; } } } else { y=ok(s[x].data-r);if(y==0){ r=r-(s[x].data-s[1].data); x=1; sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++;}else{r=r-p*R;t=1;} } else { jilv[0]=jilv[1]; jilv[1]=x; } } continue;}if(s[x].data-r==s[y].data){end=y;break;}else if(s[x].data==s[y+1].data){end=x;break;}else{r=r-(s[x].data-s[y+1].data);x=y+1;}sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++;}else{r=r-p*R;t=1;} } else { jilv[0]=jilv[1]; jilv[1]=x; } } }}printf("%d\n",s[end].id);}}return 0;}int ok(long long x){int u1=1,u2=n;int mid=0;while(u1<=u2){mid=(u1+u2)/2; if(s[mid].data<x) { u1=mid+1;}else if(s[mid].data>x){u2=mid-1;}else{return mid;}}return u2;}
相关文章推荐
- spark概念、编程模型和模块概述
- Log API 性能总结
- MFC查找所有后缀文件获取文件大小读取特定位置数据
- 安卓linearLayout动态添加控件
- spark概念、编程模型和模块概述
- 反转链表
- php安装扩展错误:Cannot find config.m4. Make sure that you run /usr/local/bin/phpize in the top level sourc
- Udemy上Gephi教程笔记1
- c# lua 简单交互
- [nRF51822] 6、基于nRF51822平台的flash读写研究
- 登录超时session丢失
- 魏昊卿——《Linux内核分析》第四周作业:系统调用的工作机制
- Zookeeper学习
- Android四大组件之 Service
- vector.resize 与 vector.reserve的区别
- python 对中文文件求交集、并集、差集
- 幂方分级
- 正则表达式
- ABAP 将SAP用户ID转换成用户名
- margin:0 auto在ie7浏览器里面无效