https://www.cnblogs.com/violet-acmer/p/10035971.html
题意:
一本书有n页,每次只能翻 d 页,问从x页到y页需要翻动几次?
注意:往前翻最少翻到第1页,往后翻最多翻到n页。
题解:
一开始想找规律来着,emmmm,直接用广搜,当时竟然过了,第二天,加数据了,直接就TLE了。
然后,今天下午,mxl给我和lk讲了一下ta的做法,找的规律,啊啊啊,我竟然没想到。
规律:
(1):如果abs(x-y)%d == 0,那么,那么直接输出abs(x-y)/d;
(2):如果abs(x-y)%d != 0,并且(y-1)%d != 0 && (n-y)%d != 0,输出-1。
对(2)的理解:如果abs(x-y)%d != 0,说明不可能从x直接翻到y,那么,只能通过从 x ->1 -> y 或 x -> n -> y了,但如果1不能翻到y并且n也不能翻到y,那肯定
就不会从x翻到y了,所以输出-1。
(3):如果前两种情况都不满足,说明 x 可以通过 (x ->1 -> y) 或 (x -> n -> y) 翻到y,然后,只需输出两中方式的最少翻动的次数即可。
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 using namespace std; 6 #define INF 0x3f3f3f3f 7 8 int n,x,y,d; 9 10 int Solve() 11 { 12 int sub=abs(x-y);//规律(1) 13 if(sub%d == 0) 14 return sub/d; 15 if((y-1)%d != 0 && (n-y)%d != 0)//规律(2) 16 return -1; 17 18 int xToOne=(x-1)/d+((x-1)%d == 0 ? 0:1); 19 int oneToY=((y-1)%d == 0 ? (y-1)/d:INF);//注意:此处是判断能否有1到y,如果不能,赋值为INF 20 21 int xToN=(n-x)/d+((n-x)%d == 0 ? 0:1); 22 int nToY=((n-y)%d == 0 ? (n-y)/d:INF);//同上 23 24 return min(xToOne+oneToY,xToN+nToY);//规律(3) 25 } 26 int main() 27 { 28 int t; 29 scanf("%d",&t); 30 while(t--) 31 { 32 scanf("%d%d%d%d",&n,&x,&y,&d); 33 printf("%d ",Solve()); 34 } 35 return 0; 36 }