题意:额,很容易懂的吧。假设每一个细胞里面都有一个数字,规律就是上面这样,然后一个细胞只能通过细胞壁到相邻的另一个细胞,问给你两个数字,求他们之间最短的距离是闹哪样。
我感觉是一道开脑洞的YY题。上午刚好看到这题想了一下思路,感觉很麻烦啊。。。然后下午去上课的时候自己睡会,脑海里都是这个图形的模拟,然后刷刷刷起来在本子上写下几行代码,然后自己在测数据,发现几处漏洞,继续duang加特技,然后感觉ok了,只等着回去敲。
首先我是这样做的,求出这两个数分别是在第几行。根据每行最后一位数字是一个平方数可以求出来。然后从上面往下面走有一种情况需要满足,那就是细胞壁相邻,但是duang的一下有些不能直接走下来,要先走到同行相邻的细胞才可以。这里就是a&1!=n&1的情况。然后l,r分别表示第一个数在据这行第一个数和最后一个数的距离。l1,r1分别表示第二个数的。。。。然后从上面一行走到下面一行每次需要2步。然后看l,r会不会在l1,r1这个范围内,是的话,就可以通过(b-a-1)*2直接走到。否则就还需要走到最靠近第二个数的位置再在同行内走l-l1+1步或者r-r1+1步。就是这样了。
#include<limits>
#include<queue>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define LL long long
#define eps 1e-8
#define pi acos(-1)
#define INF 0x7fffffff
#define delta 0.98 //模拟退火递增变量
using namespace std;
int main(){
int n,m,i;
while (~scanf("%d%d",&n,&m)){
int a=0,b=0;
if (n>m){
n=n+m;
m=n-m;
n=n-m;
}
for (i=1;;i++){
if (a==0 && i*i>=n) a=i;
if (i*i>m){
b=i;
break;
}
}
//cout<<a<<" "<<b<<endl;
if (a==b){
cout<<m-n<<endl;
continue;
}
int l,r,l1,r1;
l=n-(a-1)*(a-1);
r=a*a-n+1;
l1=m-(b-1)*(b-1);
r1=b*b-m+1;
int ans=1;
if ((a&1)!=(n&1)){
l--;
r--;
ans++;
}
if (l<=l1 && r<=r1){
ans+=(b-a-1)*2;
if ((b & 1)==(m & 1)) ans++;
}
else{
if (l1<l) ans+=(b-a-1)*2+l-l1+1;
else ans+=(b-a-1)*2+r-r1+1;
}
cout<<ans<<endl;
}
return 0;
}