【Codingame】Shadows of the Knight - Episode 1(medium)

 题目

The Goal

You will look for the hostages on a given building by jumping from one window to another using your grapnel gun. Your goal is to jump to the window where the hostages are located in order to disarm the bombs. Unfortunately, you have a limited number of jumps before the bombs go off...

 Rules

Before each jump, the heat-signature device will provide you with the direction of the bombs based on your current position:

  • U (Up)
  • UR (Up-Right)
  • R (Right)
  • DR (Down-Right)
  • D (Down)
  • DL (Down-Left)
  • L (Left)
  • UL (Up-Left)


Your mission is to program the device so that it indicates the location of the next window you should jump to in order to reach the bombs' room as soon as possible.

Buildings are represented as a rectangular array of windows, the window in the top left corner of the building is at index (0,0).

 Note

For some tests, the bombs' location may change from one execution to the other: the goal is to help you find the best algorithm in all cases.

The tests provided are similar to the validation tests used to compute the final score but remain different.

 Game Input

The program must first read the initialization data from standard input. Then, within an infinite loop, read the device data from the standard input and provide to the standard output the next movement instruction.

Initialization input

Line 1 : 2 integers W H. The (W, H) couple represents the width and height of the building as a number of windows.

Line 2 : 1 integer N, which represents the number of jumps you can make before the bombs go off.

Line 3 : 2 integers X0 Y0, representing your starting position.

Input for one game turn

The direction indicating where the bomb is.

Output for one game turn

A single line with 2 integers X Y separated by a space character. (X, Y) represents the location of the next window you should jump to. X represents the index along the horizontal axis, Y represents the index along the vertical axis. (0,0) is located in the top-left corner of the building.

Constraints

1 ≤ W ≤ 10000
1 ≤ H ≤ 10000
2 ≤ N ≤ 100
0 ≤ X, X0 < W
0 ≤ Y, Y0 < H
Response time per turn ≤ 150ms
Response time per turn ≤ 150ms

解题代码

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
 **/

struct pos
{
    int x;
    int y;
};

pos getMid(string dir, int x0, int y0, int& t, int& b, int& l, int& r)
{
    cerr << dir << " ";
    pos res;
    res.x = x0;
    res.y = y0;
    if (dir.size() == 1)
    {
        if (!dir.compare("U"))
        {
            res.y = (y0 + t) / 2;
            l = x0;
            r = x0;
            b = y0;
            cerr << "1 ";
        }
        if (!dir.compare("D"))
        {
            res.y = (y0 + b) / 2;
            l = x0;
            r = x0;
            t = y0;
            cerr << "2 ";
        }
        if (!dir.compare("L"))
        {
            res.x = (x0 + l) / 2;
            t = y0;
            b = y0;
            r = x0;
            cerr << "3 ";
        }
        if (!dir.compare("R"))
        {
            res.x = (x0 + r) / 2;
            t = y0;
            b = y0;
            l = x0;
            cerr << "4 ";
        }
    }
    else
    {
        if (dir[0] == 'U')
        {
            res.y = (y0 + t) / 2;
            cerr << "5 ";
            if (dir[1] == 'L')
            {
                res.x = (x0 + l) / 2;
                r = x0;
                b = y0;
                cerr << "1 ";
            }
            else if(dir[1] == 'R')
            {
                res.x = (x0 + r) / 2;
                l = x0;
                b = y0;
                cerr << "2 ";
            }
        }
        else if(dir[0] == 'D')
        {
            res.y = (y0 + b) / 2;
            cerr << "6 ";
            if (dir[1] == 'L')
            {
                res.x = (x0 + l) / 2;
                t = y0;
                r = x0;
                cerr << "1 ";
            }
            else if (dir[1] == 'R')
            {
                res.x = (x0 + r) / 2;
                t = y0;
                l = x0;
                cerr << "2 ";
            }
        }
    }
    return res;
}

int main()
{
    int w; // width of the building.
    int h; // height of the building.
    cin >> w >> h; cin.ignore();
    int n; // maximum number of turns before game over.
    cin >> n; cin.ignore();
    int x0;
    int y0;
    cin >> x0 >> y0; cin.ignore();

    int xc = x0;
    int yc = y0;

    int top = 0;
    int bottm = h;
    int left = 0;
    int right = w;

    cerr << w << " " << h << " ";
    // game loop
    while (1) {
        string bomb_dir; // the direction of the bombs from batman's current location (U, UR, R, DR, D, DL, L or UL)
        cin >> bomb_dir; cin.ignore();

        // Write an action using cout. DON'T FORGET THE "<< endl"
        // To debug: cerr << "Debug messages..." << endl;

        pos result = getMid(bomb_dir, xc, yc, top, bottm, left, right);
        xc = result.x;
        yc = result.y;
        cerr << top << " " << bottm << " " << left << " " << right << " ";
        cout << result.x << " " << result.y << endl;
        // the location of the next window Batman should jump to.
        
    }
}

解析

本题通过二分查找法查找目标位置,由于不用判断目标区间,降低了一些复杂度。

给定网格状棋盘的宽和高,以及人物的初始位置,通过在每一个循环体输入方向来提示目标位置的区间。每次要根据方向缩小区间,而方法就是首先判断是否在四个正方向,随后判断在斜向方向的区域内,并缩小可能区间,每次输入可能区间的坐标,并在获得输入时改变可能的区间。通过多次二分即可找到目标位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值