您的位置:首页 > 其它

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;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: