{题解}[jzoj4823] 【NOIP2016提高A组集训第1场10.29】小W学物理
2016-10-29 15:40
369 查看
传送门
镜子两个面都能反光,而中间不透光,例如,对于一个“/”型镜子,下方向射入的光线会被反射到右方向,左方向射入的光线会被反射到上方向。
现在有一条光线从原点沿X轴正方向射出,求走过T路程后所在位置。
对于100%的数据:N<=100,000,M<=1,000,000,000,T<=10^18
如果用镜子摆成一个环,那你该如何进入呢?!
准确的说,还是会出现环的。
因为可以一开始就在环里……
也就是说,唯一的环一定会经过原点!
特判即可。
也因为没有环,
所以同一面镜子不会重复经过。
最坏情况O(2n)
注意细节。
Tips:从一面镜子走向另一面镜子时,
只需要排序,就是序列中的下一面镜子
Description
为了测试小W的物理水平,Mr.X在二维坐标系中放了N面镜子(镜子坐标绝对值不超过M),镜子均与坐标轴成45°角,所以一共有两种类型“/”和“\”。原点不会有镜子,任意一点最多只有一面镜子。镜子两个面都能反光,而中间不透光,例如,对于一个“/”型镜子,下方向射入的光线会被反射到右方向,左方向射入的光线会被反射到上方向。
现在有一条光线从原点沿X轴正方向射出,求走过T路程后所在位置。
对于100%的数据:N<=100,000,M<=1,000,000,000,T<=10^18
Analysis
很显然,不会出现环。如果用镜子摆成一个环,那你该如何进入呢?!
准确的说,还是会出现环的。
因为可以一开始就在环里……
也就是说,唯一的环一定会经过原点!
特判即可。
也因为没有环,
所以同一面镜子不会重复经过。
最坏情况O(2n)
注意细节。
Tips:从一面镜子走向另一面镜子时,
只需要排序,就是序列中的下一面镜子
千万不要作死二分!!!!
Code
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const long long N = 101000, M = 1001000000, T = 1000000000000000000; const long long ctbx[4]={-1,1,0,0}, ctby[4]={0,0,1,-1}, zx[3][4]={{0,0,0,0},{3,2,1,0},{2,3,0,1}}; struct node { long long x,y,num; }a ; bool cmp(node x,node y){return (x.x<y.x)||((x.x==y.x)&&(x.y<y.y));} bool cmp2(node x,node y){return (x.y<y.y)||((x.y==y.y)&&(x.x<y.x));} long long n,m,t; long long s,Ansx,Ansy; long long w [4],num [4]; long long bz [4],c [3]; int main() { freopen("mir.in","r",stdin);freopen("mir.out","w",stdout); long long f = 1; scanf("%lld%lld%lld", &n, &m, &t); for (int i = 1;i <= n;i ++) { char ch; scanf("%lld %lld %c\n", &a[i].x, &a[i].y, &ch); c[i][2] = (ch=='/')?1:2; a[i].num = i; c[i][0] = a[i].x, c[i][1] = a[i].y; } //a[i] x,y坐标 d序号(方便其他数组) sort(a + 1, a + n + 1, cmp); for (int i = 1;i <= n;i ++) { if (a[i - 1].x == a[i].x) w[a[i].num][3] = a[i].y - a[i - 1].y, num[a[i].num][3] = a[i - 1].num; //a[i-1].y较小 if (a[i + 1].x == a[i].x) w[a[i].num][2] = a[i + 1].y - a[i].y, num[a[i].num][2] = a[i + 1].num; //a[i+1].y较大 //num[i] 原序号为i的镜子 ([0]上[1]下[2]右[3]左)第一个镜子序号 //w[i] 原序号为i的镜子 ([0]上[1]下[2]右[3]左)第一个镜子距离 } sort(a + 1,a + n + 1,cmp2); for (int i = 1;i <= n;i ++) { if (a[i - 1].y == a[i].y) w[a[i].num][0] = a[i].x - a[i - 1].x, num[a[i].num][0] = a[i - 1].num; if (a[i + 1].y == a[i].y) w[a[i].num][1] = a[i + 1].x - a[i].x, num[a[i].num][1] = a[i + 1].num; //优化:先走几步... if (a[i].y == 0 && a[i].x > 0 && s == 0) if (a[i].y < t) s = a[i].num, t -= a[i].x; else Ansx = t, Ansy = 0, t = 0; } if (s == 0) Ansx = t, Ansy = 0, t = 0; for(;t;) { if(bz[s][f] != 0) t = t % (bz[s][f] - t); //bz判环 bz[s][f] = t; f = zx[c[s][2]][f]; //zx 转向专用数组! //f 方向 if (w[s][f] < t && num[s][f] != 0) t -= w[s][f], s = num[s][f]; //考虑走几步... else Ansx = c[s][0] + ctbx[f] * t, Ansy = c[s][1] + ctby[f] * t, t = 0; } printf("%lld %lld", Ansx, Ansy); }
相关文章推荐
- {题解}[jzoj4823] 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ 4823 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ 4823. 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ4823. 【NOIP2016提高A组集训第1场10.29】小W学物理
- NOIP2016提高A组集训第1场【JZOJ4823】小W学物理
- 小W学物理【NOIP2016提高A组集训第1场10.29】
- 【NOIP2016提高A组集训第1场10.29】小W学物理
- 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ 4822 【NOIP2016提高A组集训第1场10.29】完美标号
- JZOJ 4824. 【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- JZOJ 4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- JZOJ 4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
- 【NOIP2016提高A组集训第1场10.29】完美标号
- {题解}[jzoj4882]【NOIP2016提高A组集训第12场11.10】多段线性函数
- 【NOIP2016提高A组集训第1场10.29】完美标号
- 【NOIP2016提高A组集训第1场10.29】完美标号
- 完美标号【NOIP2016提高A组集训第1场10.29】
- 【NOIP2016提高A组集训第1场10.29】配对游戏