牛客假日团队赛12【为了抽奖闲来做题2】

在这里插入图片描述

A题

链接:https://ac.nowcoder.com/acm/contest/1081/A
来源:牛客网

Bessie is trapped in a triangular maze with N rows (1 <= N <= 1,000,000). A three row maze is shown below:
The i’th row of the maze contains 2*i-1 triangles. Numbering from the left, the triangles are named (i,1), (i,2), and so on.
Bessie can travel to the (often three) triangles which share an edge with her current triangle. For example, if she is at (3, 3), she can travel to (3, 2), (3, 4) and (4, 4). Bessie takes one minute to travel from one triangle to the next.
FJ has learned the Bessie is trapped and knows by tracking her iPhone that she starts her exit trek at triangle (Si,Sj). FJ’s love for Bessie knows no bounds so he wants her back in the minimum possible time.
The maze has M (1 <= M <= 10,000) exits found in locations throughout the set of triangles. Any one of these will enable Bessie to escape. Once she enters an exit triangle, she leaves the maze in just one more minute.
Find the minimum time in minutes, T, required for Bessie to exit the maze and report the optimal exit location she uses, (OUTi, OUTj). If more than one location requires only T minutes, output the location with the smallest row. If two optimal rows are the same, output the one with smaller column.

输入描述:

  • Line 1: Two space-separated integers: N and M
  • Line 2: Two space-separated integers: Si and Sj
  • Lines 3…M+2: Line i+2 contains two space-separated integers that are the triangle location of exit i: Ei and Ej

输出描述:

  • Line 1: Two space-separated integers: OUTi and OUTj
  • Line 2: A single integer: T

输入

4 2
2 1
3 5
4 4

输出

4 4
4

AC Code

距离可以在O(1)的时间内计算,枚举出口计算距离,更新最小值即可。

/*
 * Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
 * @Author: Ng Kimbing, HNU.
 * @LastModified:2019-08-25 T 15:27:36.369 +08:00
 */
 
#include <bits/stdc++.h>
#include <ostream>
 
using namespace std;
#define eps 1e-9
const int MAX_N = 220;
 
class Triangle {
   
    public:
        int row;
        int id;
 
        explicit Triangle(int row = 0, int id = 0) : row(row), id(id) {
   }
 
        bool operator<(const Triangle &rhs) const {
   
            if (row < rhs.row)
                return true;
            if (rhs.row < row)
                return false;
            return id < rhs.id;
        }
 
        friend ostream &operator<<(ostream &os, const Triangle &triangle) {
   
            os << triangle.row << " " << triangle.id;
            return os;
        }
} ans;
 
class Result {
   
    public:
        Triangle triangle;
        int _time;
 
        Result() {
    _time = 0x3f3f3f3f; }
 
        Result(const Triangle &triangle, int _time = 0) : triangle(triangle), _time(_time) {
   }
 
        bool operator<(const Result &rhs) const {
   
            return _time < rhs._time;
        }
 
        friend ostream &operator<<(ostream &os, const Result &result) {
   
            os << result.triangle << "\n" << result._time + 1;
            return os;
        }
};
 
vector<Triangle> triangles;
 
int getRowDis(int r1, int id1, int r2, int id2) {
   
    bool isUp1 = true, isUp2 = true;
    if (id1 & 1)
        isUp1 = false;
    if (id2 & 1)
        isUp2 = false;
    int foo = 2 * (r2 - r1);
    if (isUp1 && !isUp2)
        return foo + 1;
    if (!isUp1 && isUp2)
        return foo - 1;
    return foo;
}
 
int getDis(int r1, int id1, int r2, int id2) {
   
    //ensure that r1 <= r2
    if (r1 > r2) {
   
        swap(r1, r2);
        swap(id1, id2);
    }
    int res = getRowDis(r1, id1, r2, id2);
    if (id1 <= id2) {
   
        return max(id2 - id1, res);
    } else {
   
        int gap = id1 - id2;
        return getDis(r1, id2, r2, id2) + gap;
    }
}
 
int main() {
   
    int n, m, sRow, sId;
    Result ans;
    cin >> n >> m >> sRow >> sId;
    for (int i = 0; i < m; i++) {
   
        int row, id;
        cin >> row >> id;
        triangles.emplace_back(row, id);
    }
    sort(triangles.begin(), triangles.end());
    for (auto &currTriangle:triangles) {
   
        int r1 = currTriangle.row, r2 = sRow, id1 = currTriangle.id, id2 = sId;
        ans = min(ans, Result(currTriangle, getDis(r1, id1, r2, id2)));
    }
    cout << ans;
    return 0;
}

B题

链接:https://ac.nowcoder.com/acm/contest/1081/B
来源:牛客网

题目描述

明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

证词中出现的其他话,都不列入逻辑推理的内容。

明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

输入描述:

输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。
往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。

输出描述:

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

输入

3 1 5
MIKE
CHARLES
KATE
MIKE: I am guilty.
MIKE: Today is Sunday.
CHARLES: MIKE is guilty.
KATE: I am guilty.
KATE: How are you??

输出

MIKE

Solution

 枚举犯人和今天是星期几,对每个枚举的情况判断说谎和说实话的人数即可。
(处理起来较繁琐)

部分代码

    static ArrayList<String> crimeName = new ArrayList<>();
    static ArrayList<Evidence> evidences = new ArrayList<>();
    private static Map<String, Integer> s2i = new HashMap<>();
 
    static {
   
        s2i.put("Monday", 1);
        s2i.put("Tuesday", 2);
        s2i.put("Wednesday", 3);
        s2i.put("Thursday", 4);
        s2i.put("Friday", 5);
        s2i.put("Saturday", 6);
        s2i.put("Sunday", 7);
    }
 
    public static void main(String[] args) throws Exception {
   
        int m = nextInt(), n = nextInt(), q = nextInt();
        for (int i = 0; i < m; ++i)
            crimeName.add(next());
        for (int i = 0; i < q; ++i) {
   
            String line = nextLine();
            int pos = line.indexOf(": ");
            String sayer = line.substring(0, pos);
            String sentence = line.substring(pos + 2);
            if (sentence.equals("I am guilty."))
                evidences.add(new NameEvidence(sayer, sayer, false));
            else if (sentence.contains("is guilty")) {
   
                String name = sentence.substring(0, sentence.indexOf("is guilty") - 1);
                evidences.add(new NameEvidence(sayer, name, false));
            } else if (sentence.contains("Today is")) {
   
                String dow = sentence.substring(9);
                evidences.add(new WeekEvidence(sayer, s2i.get(dow.substring(0, dow.length() - 1))));
            } else if (sentence.contains("I am not guilty"))
                evidences.add(new NameEvidence(sayer, sayer, true));
            else if (sentence.contains("is not guilty")) {
   
                String name = sentence.substring(0, sentence.indexOf("is not guilty") - 1);
                evidences.add(new NameEvidence(sayer, name, true));
            }
        }
        Set<String> fakeSayers = new HashSet<>();
        Set<String> trueSayer = new HashSet<>();
        Set<String> ans = new HashSet<>();
        for (String name : crimeName) {
   
            for (int i = 1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值