Problem G GentleBots(对结构体的使用值得学习)

题目链接:https://vjudge.net/problem/Gym-101606G

题目:
Rainforest Inc. is opening a large new automated warehouse in the far Northern reaches of the
UK—some place they call “Walthamstow”.
The robotic worker drones inside will operate in not just one or two, but three dimensions, and
can move in any one of the 6 cardinal dimensions in steps of 1 metre at a time. For example,
a robot looking to move from position (X1, Y1, Z1) to position (X2, Y2, Z2) will, assuming no
obstacles, need to take (|X2 − X1| + |Y2 − Y1| + |Z2 − Z1|) steps in total.
Since this warehouse is in Britain, and because every stereotype is true, the robotic denizens are
all impeccably polite. When two robots travelling in opposite directions meet, they wordlessly
negotiate for one of the robots to step aside somehow so the other can pass.
Multiple robots cannot occupy the same integer co-ordinates, and no two robots can swap
positions in one move. All moves are instantaneous.
We have prepared a test run of the warehouse with just two machines installed. Write a program
to pass this test.
Input
Two lines, one for each robot, each containing six space-separated integers (X0Y0Z0) and
(X∞Y∞Z∞), the intended start and end locations of a robot respectively (−1000 ≤ X, Y, Z ≤
1000).
The robots will start in different places from each other, and will also end in different places
from each other.
Output
Output up to 7000 lines, giving one possible list of locations of the robots over time. The position
of both robots at time T must be given as bracketed space-separated (X, Y, Z) co-ordinate tuples
on line T.
Co-ordinates must not exceed an absolute value of 106
.
Sample Input 1 Sample Output 1
0 0 0 2 2 2
1 1 2 0 0 0
(0 0 0) (1 1 2)
(1 0 0) (1 1 1)
(1 1 0) (0 1 1)
(1 1 1) (0 1 0)
(1 1 2) (0 0 0)
(1 2 2) (0 0 0)
(2 2 2) (0 0 0)
Sample Input 2 Sample Output 2
-2 0 0 1 0 0
3 0 0 -1 0 0
(-2 0 0) (3 0 0)
(-1 0 0) (2 0 0)
(0 0 0) (1 0 0)
(1 0 0) (1 0 -1)
(1 0 0) (0 0 -1)
(1 0 0) (-1 0 -1)
(1 0 0) (-1 0 0)
Sample Input 3 Sample Output 3
0 0 0 1 0 0
1 0 0 0 0 0
(0 0 0) (1 0 0)
(0 1 0) (0 0 0)
(1 1 0) (0 0 0)
(1 0 0) (0 0 0

题意: 一个三维的坐标系中,给你两个机器人的起点坐标和终点坐标,每个机器人在1s内只能向x或者y或者z方向运动一个单位或者不动,让你输出每一秒两个机器人的坐标,答案有很多种,输出任何一种即可。两个机器人都是同时运动的,不可以同时在同一个坐标上,两个机器人也不可以交替运动(一个机器人边离开这个坐标,另一个机器人边进入这个坐标)。

思路:设估价函数为两点到终点的曼哈顿距离之和,每次选取使得估价函数最优的方向走,若不能走,则随机抖动。

代码转自一位大佬https://www.cnblogs.com/clrs97/p/7768748.html

#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int dx[7]={1,-1,0,0,0,0,0},
          dy[7]={0,0,-1,1,0,0,0},
          dz[7]={0,0,0,0,1,-1,0};
struct P{
    int x,y,z;
    void read(){
        scanf("%d%d%d",&x,&y,&z);
    }
    int dis(P b){
        return abs(x-b.x)+abs(y-b.y)+abs(z-b.z);
    }
    void write(){
        printf("(%d %d %d)",x,y,z);
    }
    P(){}
    P(int _x,int _y,int _z){x=_x,y=_y,z=_z;}
    P apply(int d){
        return P(x+dx[d],y+dy[d],z+dz[d]);
    }
}A,B,C,D;//A->B C->D
int main(){
    A.read();
    B.read();
    C.read();
    D.read();
    while(1){
        A.write();
        putchar(' ');
        C.write();
        puts("");
        int pre=A.dis(B)+C.dis(D);
        if(!pre)return 0;
        int best=~0U>>1;
        int I=0,J=0;
        for(int i=0;i<7;i++)for(int j=0;j<7;j++){
            P NA=A.apply(i),NC=C.apply(j);
            if(!NA.dis(C))continue;
            if(!NA.dis(NC))continue;
            if(!NC.dis(A))continue;
           // if(!NC.dis(NA))continue;
            int now=NA.dis(B)+NC.dis(D);
            if(now<best)best=now,I=i,J=j;
        }
        if(best>=pre){
            while(1){
                int i=rand()%7,j=rand()%7;
                P NA=A.apply(i),NC=C.apply(j);
                if(!NA.dis(C))continue;
                if(!NA.dis(NC))continue;
                if(!NC.dis(A))continue;
               // if(!NC.dis(NA))continue;
                I=i,J=j;
                break;
            }
        }
        A=A.apply(I);
        C=C.apply(J);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值