UVALive 7528(2015德黑兰区域赛) Beehive
2016-03-24 22:49
405 查看
UVALive 7528(2015德黑兰区域赛) Beehive
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=695&page=show_problem&problem=5550
题目大意:
如图所示,在一个平面上,六边形按图中所示方式排列,问任意两个格子之间需要走多少步才能到达。(经过一个格子算一步)
格子1算作第1圈,可以看出偶数圈比上一圈多2个格,奇数圈多4个。
先初始化跑一遍,存一下所有格子所在圈数,每一圈的起始格子号,每一圈的格子数量。
设格子1坐标为(0,0),横着的一个格算1,竖着的通过横边向上的算2,斜边的算1。对于输入的一个号码a,通过以下方式获取该格子的坐标。
step0
首先查找当前格子所处圈数n,first,mid,last分别是当前圈的最左边,中间,最右边的格子。获取当前格子与mid的数字差d=|a-mid|
step1 计算横坐标x。
易知mid在1的正上方,即横坐标为0,由图可以看出mid两侧逐渐斜着向两侧拓展,没拓展一格横坐标向外加一。又因为每一圈向左右两侧最远伸展为n-1,所以|x|=min(d,n-1),至于x的正负很好判断不用我说了。
step2 计算纵坐标y。
由图形可以发现,格子是由两侧到中间逐渐升高的,所以只需知道升高了多少就行了。获取一下该格子到两侧的最小距离y0=min(a-first,last-a)。此外,偶数圈会比奇数圈多出半个格子高的起始点,所以起始高度yb=n%2==0?1:0。
由这个图可以看出,当n>3后,每一圈会有dn个格子是垂直上升的,其中dn=(n-1)/2
所以y=yb+2*dn+max(y0-dn,0)
最后一步,计算两个格子间距
获取两个格子的坐标p1,p2后,计算一下横纵坐标差,由对称性可以直接取绝对值dx=abs(p1.x-p2.x),dy=abs(p1.y-p2.y)
如果dx=0,或者dy=0,或者两个格子在同一斜排(dx=dy),直接算即可dis=max(dx,dy)。
可以看出来,任意不在一排的两个点都是可以看做一个平行四边形的对角顶点,而最近的走法就是在整个平行四边形内部走,而且,只要是在内部,不走回头路的话,走的距离都是一样的。
所以,对于dx>dy的情况,距离dis=dx
对于dy>dx的情况,dis=dx+(dy-dx)/2
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=695&page=show_problem&problem=5550
题目大意:
如图所示,在一个平面上,六边形按图中所示方式排列,问任意两个格子之间需要走多少步才能到达。(经过一个格子算一步)
格子1算作第1圈,可以看出偶数圈比上一圈多2个格,奇数圈多4个。
先初始化跑一遍,存一下所有格子所在圈数,每一圈的起始格子号,每一圈的格子数量。
设格子1坐标为(0,0),横着的一个格算1,竖着的通过横边向上的算2,斜边的算1。对于输入的一个号码a,通过以下方式获取该格子的坐标。
step0
首先查找当前格子所处圈数n,first,mid,last分别是当前圈的最左边,中间,最右边的格子。获取当前格子与mid的数字差d=|a-mid|
step1 计算横坐标x。
易知mid在1的正上方,即横坐标为0,由图可以看出mid两侧逐渐斜着向两侧拓展,没拓展一格横坐标向外加一。又因为每一圈向左右两侧最远伸展为n-1,所以|x|=min(d,n-1),至于x的正负很好判断不用我说了。
step2 计算纵坐标y。
由图形可以发现,格子是由两侧到中间逐渐升高的,所以只需知道升高了多少就行了。获取一下该格子到两侧的最小距离y0=min(a-first,last-a)。此外,偶数圈会比奇数圈多出半个格子高的起始点,所以起始高度yb=n%2==0?1:0。
由这个图可以看出,当n>3后,每一圈会有dn个格子是垂直上升的,其中dn=(n-1)/2
所以y=yb+2*dn+max(y0-dn,0)
最后一步,计算两个格子间距
获取两个格子的坐标p1,p2后,计算一下横纵坐标差,由对称性可以直接取绝对值dx=abs(p1.x-p2.x),dy=abs(p1.y-p2.y)
如果dx=0,或者dy=0,或者两个格子在同一斜排(dx=dy),直接算即可dis=max(dx,dy)。
可以看出来,任意不在一排的两个点都是可以看做一个平行四边形的对角顶点,而最近的走法就是在整个平行四边形内部走,而且,只要是在内部,不走回头路的话,走的距离都是一样的。
所以,对于dx>dy的情况,距离dis=dx
对于dy>dx的情况,dis=dx+(dy-dx)/2
#include<stdio.h> #include<iostream> #include<stdlib.h> #include<ctype.h> #include<string.h> #include<string> #include<algorithm> #include<math.h> using namespace std; #define N 10002 struct Pos { int x,y; Pos(int a=0,int b=0):x(a),y(b){} void show() { cout<<x<<' '<<y<<endl; } }; int rd ; int fp[100],num[100]; void init() { int now=1,time=1,sum=0; for(int i=1;i<=10000;i++) { rd[i]=time; if (sum==0) fp[time]=i,num[time]=now; sum++; if (sum==now) { sum=0; time++; if (time%2==0) now+=2; else now+=4; } } //cout<<time<<endl; // for(int i=1;i<22;i++) cout<<fp[i]<<' ';cout<<endl; // for(int i=1;i<22;i++) cout<<i<<' '<<rd[i]<<endl; } Pos getpos(int a) { if (a==1) return Pos(0,0); int n=rd[a]; int first=fp ,last=fp +num -1; int mid=(first+last)/2; if (a==mid) return Pos(0,n*2-2); int x0=0; int c=abs(a-mid)/(a-mid); int x=c*min(abs(a-mid),n-1),y; int yb=n%2==0?1:0; int dn=(n-1)/2; int y0=min(a-first,last-a); y=yb+2*dn+max(y0-dn,0); // cout<<"round="<<n<<" 1st:"<<first<<" mid:"<<mid<<" last:"<<last<<" x0="<<x0<<" y0="<<y0<<" x,y="<<x<<" "<<y<<endl; return Pos(x,y); } int main() { init(); int a,b; while(cin>>a>>b) { if (a+b==0) return 0; if (a==b) {puts("0");continue;} Pos p1=getpos(a),p2=getpos(b); //p1.show(),p2.show(); int dx=abs(p1.x-p2.x),dy=abs(p1.y-p2.y); // cout<<dx<<' '<<dy<<endl; if (dx==dy||dy==0||dx>dy) {cout<<dx<<endl;continue;} if (dx==0) {cout<<dy/2<<endl;continue;} cout<<dx+(dy-dx)/2<<endl; } return 0; }
相关文章推荐
- 小学生算数测试
- SSH框架整合发现的问题,必须放置在Spring中配置
- xss漏洞利用
- 服务端PHP设置cookie,客户端未生效
- 服务端PHP设置cookie,客户端未生效
- ubuntu12.04安装nginx
- Leetcode #22 Generate Parentheses 创建括号 解题报告
- 我是一只新晋程序狗
- 网络流(最大流):COGS 28 [NOI2006] 最大获利
- 安装ubuntu14.04
- 【CV】CVPR2015_A Discriminative CNN Video Representation for Event Detection
- 树状数组的小总结
- 5 分钟上手 ECharts(echart官网转载)
- 用程序打印万年历
- 字符串分离方法
- RSA 数字签名 免密码登录
- PHP为什么会被认为是草根语言?
- 泛型(三)
- WAF安恒
- Wooden Sticks