Problem Statement |
|||||||||||||
Fox Ciel has a robot. The robot is located on an infinite plane. At the beginning, the robot starts at the coordinates (0, 0). The robot can then make several steps. The steps are numbered starting from 0. In each step, Ciel must choose one of four directions for the robot: left (x coordinate decreases), right (x coordinate increases), up (y coordinate increases), or down (y coordinate decreases). In step k, the robot will move 3^k units in the chosen direction. It is not allowed to skip a step. You are given ints x and y. Return "Possible" (quotes for clarity) if it is possible that the robot reaches the point (x,y) after some (possibly zero) steps. Otherwise, return "Impossible". |
|||||||||||||
Definition |
|||||||||||||
|
|||||||||||||
Limits |
|||||||||||||
|
|||||||||||||
Constraints |
|||||||||||||
- | x will be between -1,000,000,000 and 1,000,000,000, inclusive. | ||||||||||||
- | y will be between -1,000,000,000 and 1,000,000,000, inclusive. | ||||||||||||
Examples |
|||||||||||||
0) | |||||||||||||
|
|||||||||||||
1) | |||||||||||||
|
|||||||||||||
2) | |||||||||||||
|
|||||||||||||
3) | |||||||||||||
|
|||||||||||||
4) | |||||||||||||
|
|||||||||||||
5) | |||||||||||||
|
|||||||||||||
6) | |||||||||||||
|
|||||||||||||
7) | |||||||||||||
|
类型:数论 图论 难度:2.5
题意:在一张图中,起点是(0,0),每次可以向上下左右四个方向走,第k次走的步数是3^k(k从0开始),给出一个坐标(x,y),-1000000000<x,y<1000000000,问这个坐标是否能走到。
分析:本题可以采用dfs等方法进行搜索,遍历所有情况,看能否到达目标点,但是后来考虑每次都加3^k,应该可以找到一些数学规律,比如每次都对3取余,然后除以3,能否判断出这个点会不会走到呢,后来推出来是可以判断的,数学推导如下:
因为第k次走3^k步,那么:x+y = (+-)3^0 (+-) 3^1 (+-)...(+-)3^k,由于数据范围为-10^9 - 10^9,并且3^20 > 10^9,所以k<20
分开写,x = (-1)^a0 * 3^b0 + (-1)^a1 * 3^b1 + ... + (-1)^ak * 3^bk,其中ak = 0,1,bk=[0,k],y的表达式相同
接下来进入循环,每次循环取x%3的值,并更新 x /= 3,考虑第k次 x%3 的值,有3种情况:
1)x%3 = 0,那么在第k步x方向没有走
2)x%3 = -1,2,在第k步向x负方向走了3^k步
3)x%3 = -2,1,在第k步向x正方向走了3^k步
y轴情况相同。
用上述方法处理x,y,用f数组记录x和y分别在那些步走了,f[i]表示x,y在第i步走的步数的和,那么最终遍历f,若f中有值的部分值都为1,所有的1是连续出现且是从0开始出现,那么点(x,y)可达,否则不可达。
注意:看了一个别人的方法,直接判断x+y,依次遍历k,然后看是否每一步都走了(余数不为0),但是后来考虑这个方法由问题,比如(6,7)这个点,6+7=13,显然13=1+3+9,但是6和7本身都不能写成 x = (-1)^a0 * 3^b0 + (-1)^a1 * 3^b1 + ... + (-1)^ak * 3^bk 的形式,所以还是要分别判断x和y。我challenge这个bug成功,还加了50分~呵呵~
代码:
#include<iostream> #include<cstring> using namespace std; class PowerOfThree { public: int f[30]; void cal(int x) { for(int i=0; x; i++,x/=3) { int tmp = x%3; if(tmp!=0) f[i]++; if(tmp==-1 || tmp==2) x++; if(tmp==-2 || tmp==1) x--; } } string ableToGet(int x, int y) { memset(f,0,sizeof(f)); cal(x);cal(y); bool isend = 0; for(int i=0; i<21; i++) { if(f[i]==0) isend = 1; if((isend && f[i]>0) || f[i]>1) return "Impossible"; } return "Possible"; } };