Topcoder SRM 345 Div1 250

题意:起初在(0,0),要到(x,y)去,每次只能横向或纵向移动。横向移动时,若所在直线y为偶数,那么只能往x轴正方向移动,若为奇数,只能往x轴反方向移动;纵向移动时,若所在直线x为偶数,那么只能往y轴正方向移动,若为奇数,只能往y轴反方向移动。问从起点到终点的最短距离是多少?

x,y 范围是[-1e6, 1e6]

解法:一开始想到bfs(想到很自然),将(0, 0), (x, y), (x, 0), (0, y)这4个点分别周围9个点(包括自己)作为可达点。bfs处理出(0, 0)到(x, y)的最短距离即可。后来发现,有直接判的方法,枚举下(x,y)在哪一象限,通过x,y的奇偶性得到答案。

第二种方法Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

class Pathfinding{
public:
    int getDirections(int x, int y){
        int ans = 0;
        if(x >= 0 && y >= 0)
        {
            if((x&1)==0 || (y&1)==0) ans = abs(x)+abs(y);
            else ans = abs(x)+abs(y)+2;
        }
        else if(x <= 0 && y <= 0)
        {
            if((x&1)==1 || (y&1)==1) ans = abs(x) + abs(y) + 2;
            else ans = abs(x) + abs(y) + 4;
        }
        else if(x > 0 && y < 0)
        {
            if((x&1)==1 || (y&1)==0) ans = abs(x) + abs(y);
            else ans = abs(x) + abs(y) + 2;
        }
        else if(x < 0 && y > 0)
        {
            if((x&1)==0 || (y&1)==1) ans = abs(x) + abs(y);
            else ans = abs(x) + abs(y) + 2;
        }
        return ans;
    }
};

第一种方法Code

#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

struct Data{
    int x,y;
    int id;
    int d;
}d[100010];
int nd;
queue<Data>q;
int t;
int minidis[100010];
void pushit(int x1,int y1){
    for(int i = -1; i <= 1; i++){
        for(int j = -1; j <= 1; j++){
            ++nd;
            d[nd].x = x1 + i, d[nd].y = y1 + j;
            d[nd].d = 1e9;
        }
    }
}
bool canget(Data d1, Data d2)
{
    if(d1.x == d2.x)
    {
        if((d1.x & 1) && d1.y >= d2.y) return true;
        if((d1.x & 1) == 0 && d1.y <= d2.y) return true;
    }
    if(d1.y == d2.y)
    {
        if((d1.y & 1) && d1.x >= d2.x) return true;
        if((d1.y & 1) == 0 && d1.x <= d2.x) return true;
    }
    return false;
}
class Pathfinding{
public:
    int getDirections(int x, int y){
        nd = 0;
        pushit(x, y);
        pushit(0, 0);
        pushit(x, 0);
        pushit(0, y);

        Data nowd;
        nowd.x = 0, nowd.y = 0, nowd.d = 0;
        q.push(nowd);
        while(!q.empty())
        {
            nowd = q.front();
            q.pop();
            for(int i = 1; i <= nd; i++)
            {
                if(canget(nowd, d[i]))
                {
                    if(nowd.d + abs(nowd.x - d[i].x) + abs(nowd.y - d[i].y) < d[i].d)
                    {
                        d[i].d = nowd.d + abs(nowd.x - d[i].x) + abs(nowd.y - d[i].y);
                        q.push(d[i]);
                    }
                }
            }
        }
        int ans = 1e9;
        for(int i = 1; i <= nd; i++)
        {
            if(d[i].x == x && d[i].y == y)
            {
                ans = min(ans, d[i].d);
            }
        }
        return ans;
    }
};

你可能感兴趣的:(Topcoder SRM 345 Div1 250)