题意:根据题目给出的数塔,问从m走到n最少需要多少步?只能通过相邻的边走动。
思路:模拟它的走动即可。
- 1.如果在同一行,直接走过去。
- 2.如果不在同一行,分情况讨论。
- 1.如果是它是这一行的奇数个,直接走到下一行。
- 2.如果是偶数个,根据在这一行的位置与m所在行的相对位置决定是往左走还是往右走。
http://acm.hdu.edu.cn/showproblem.php?pid=1030
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i ++)
#define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --)
#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)
#define cls(a,x) memset(a,x,sizeof(a))
#define eps 1e-8
using namespace std;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN = 31623;
const int MAXE = 2e5+5;
typedef long long LL;
typedef unsigned long long ULL;
int T,n,m,k;
int fx[] = {0,1,-1,0,0};
int fy[] = {0,0,0,-1,1};
void input() {
}
void solve() {
if(n > m) swap(n,m);
int n1,n2,m1,m2;
n1 = 0; m1 = 0;
for(int i = 1 ; i * i < n ; i ++) n1 = i;
n2 = n - ( n1 ) * ( n1 );
n1 ++ ;
for(int i = 1 ; i * i < m ; i ++) m1 = i;
m2 = m - ( m1 ) * ( m1 );
m1 ++ ;
int t = 0 ;
while((n1 != m1) || (n2 != m2)) {
if(n1 == m1) {
if(m2 < n2) swap(m2,n2);
t += m2 - n2 ;
n2 = m2;
}
else if(n2 % 2) {
n1 ++ ; n2 ++ ;
t ++;
}
else {
if(m2 <= (m1-n1+n2)) {
n2 -- ;
t ++;
}
else {
n2 ++;
t ++;
}
}
}
printf("%d\n",t);
}
int main(void) {
while(~scanf("%d %d",&n,&m)) {
input();
solve();
}
return 0;
}