自学内容网 自学内容网

比赛的冠亚季军

比赛的冠亚季军

真题目录: 点击去查看

E 卷 100分题型

题目描述

有N(3 ≤ N < 10000)个运动员,他们的id为0到N-1,他们的实力由一组整数表示。他们之间进行比赛,需要决出冠亚军。比赛的规则是0号和1号比赛,2号和3号比赛,以此类推,每一轮,相邻的运动员进行比赛,获胜的进入下一轮;实力值大的获胜,实力值相等的情况,id小的情况下获胜;轮空的直接进入下一轮。

输入描述

输入一行N个数字代表N的运动员的实力值(0<=实力值<=10000000000)。

输出描述

输出冠亚季军的id,用空格隔开。

用例1

输入

2 3 4 5

输出

3 1 2

说明

第一轮比赛,

id为0实力值为2的运动员和id为1实力值为3的运动员比赛,1号胜出进入下一轮争夺冠亚军,

id为2的运动员和id为3的运动员比赛,3号胜出进入下一轮争夺冠亚军,

冠亚军比赛,3号胜1号,

故冠军为3号,亚军为1号,2号与0号,比赛进行季军的争夺,2号实力值为4,0号实力值2,故2号胜出,得季军。冠亚季军为3 1 2。

题解

思路:

  1. 模拟方法去处理
  2. 主要需要考虑奇数和偶数的情况就行

c++

#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <sstream>

using namespace std;

// 运动员类
struct Sport {
    int id;          // 运动员的id
    long long strength; // 运动员的实力

    Sport(int id, long long strength) : id(id), strength(strength) {}
};

string getResult(vector<long long>& strengths);
void promote(vector<Sport>& sports, deque<vector<Sport>>& ans);

int main() {
    string input;
    getline(cin, input);

    stringstream ss(input);
    vector<long long> strengths;
    long long strength;

    while (ss >> strength) {
        strengths.push_back(strength);
    }

    cout << getResult(strengths) << endl;
    return 0;
}

string getResult(vector<long long>& strengths) {
    // ans只记录三个组,冠军组,亚军组,季军组
    deque<vector<Sport>> ans;

    // 将输入的实力值,转化为运动员集合
    vector<Sport> sports;
    for (int i = 0; i < strengths.size(); ++i) {
        sports.emplace_back(i, strengths[i]);
    }

    // 晋级赛
    promote(sports, ans);

    // 冠军组如果不是一个人,那么还需要取出冠军组继续进行晋级赛
    while (ans.front().size() > 1) {
        sports = ans.front();
        ans.pop_front();
        promote(sports, ans);
    }

    // 冠军
    int first = ans[0][0].id;

    // 亚军
    int second = ans[1][0].id;

    // 季军
    sort(ans[2].begin(), ans[2].end(), [](const Sport& a, const Sport& b) {
        return a.strength != b.strength ? a.strength > b.strength : a.id < b.id;
    });

    int third = ans[2][0].id;

    return to_string(first) + " " + to_string(second) + " " + to_string(third);
}

void promote(vector<Sport>& sports, deque<vector<Sport>>& ans) {
    // 记录获胜组
    vector<Sport> win;
    // 记录失败组
    vector<Sport> fail;

    for (int i = 1; i < sports.size(); i += 2) {
        Sport& major = sports[i];      // 序号大的运动员
        Sport& minor = sports[i - 1]; // 序号小的运动员

        if (major.strength > minor.strength) {
            win.push_back(major);
            fail.push_back(minor);
        } else {
            win.push_back(minor);
            fail.push_back(major);
        }
    }

    // 如果晋级赛中运动员个数是奇数个,那么最后一个运动员直接晋级
    if (sports.size() % 2 != 0) {
        win.push_back(sports.back());
    }

    // 依次头部压入失败组,获胜组,保证头部是获胜组
    ans.push_front(fail);
    ans.push_front(win);

    // 如果保留组个数超过3个,那么需要将超过部分的组去掉,因为这部分人已经无缘季军
    while (ans.size() > 3) {
        ans.pop_back();
    }
}

JAVA

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
  // 运动员类
  static class Sport {
    int id; // 运动员的id
    long strength; // 运动员的实力

    public Sport(int id, long strength) {
      this.id = id;
      this.strength = strength;
    }
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    long[] strengths = Arrays.stream(sc.nextLine().split(" ")).mapToLong(Long::parseLong).toArray();

    System.out.println(getResult(strengths));
  }

  public static String getResult(long[] strength) {
    // ans只记录三个组,冠军组,亚军组,季军组
    LinkedList<ArrayList<Sport>> ans = new LinkedList<>();

    // 将输入的实力值,转化为运动员集合
    ArrayList<Sport> sports = new ArrayList<>();
    for (int i = 0; i < strength.length; i++) sports.add(new Sport(i, strength[i]));

    // 晋级赛
    promote(sports, ans);

    // 冠军组如果不是一个人,那么还需要取出冠军组继续进行晋级赛
    while (ans.getFirst().size() > 1) {
      promote(ans.removeFirst(), ans);
    }

    // 冠军
    int first = ans.get(0).get(0).id;

    // 亚军
    int second = ans.get(1).get(0).id;

    // 季军
    ans.get(2)
        .sort(
            (a, b) ->
                a.strength != b.strength ? b.strength - a.strength > 0 ? 1 : -1 : a.id - b.id);
    
    int third = ans.get(2).get(0).id;
    return first + " " + second + " " + third;
  }

  public static void promote(ArrayList<Sport> sports, LinkedList<ArrayList<Sport>> ans) {
    // 记录获胜组
    ArrayList<Sport> win = new ArrayList<>();
    // 记录失败组
    ArrayList<Sport> fail = new ArrayList<>();

    for (int i = 1; i < sports.size(); i += 2) {
      // 序号大的运动员
      Sport major = sports.get(i);
      // 序号小的运动员
      Sport minor = sports.get(i - 1);

      if (major.strength > minor.strength) {
        win.add(major);
        fail.add(minor);
      } else {
        // 如果序号大的运动员的实力 <= 序号小的运动员,则序号小的运动员获胜
        win.add(minor);
        fail.add(major);
      }
    }

    // 如果晋级赛中运动员个数是奇数个,那么最后一个运动员直接晋级
    if (sports.size() % 2 != 0) {
      win.add(sports.get(sports.size() - 1));
    }

    // 依次头部压入失败组,获胜组,保证头部是获胜组
    ans.addFirst(fail);
    ans.addFirst(win);

    // 如果保留组个数超过3个,那么需要将超过部分的组去掉,因为这部分人已经无缘季军
    while (ans.size() > 3) ans.removeLast();
  }
}

Python

# 输入获取
tmp = list(map(int, input().split()))


class Sport:
    def __init__(self, idx, strength):
        self.idx = idx  # 运动员的id
        self.strength = strength    # 运动员的实力


# 将输入的实力值,转化为运动员集合
sports = []
for i in range(len(tmp)):
    sports.append(Sport(i, tmp[i]))


def promote(sports, ans):
    # 记录获胜组
    win = []
    # 记录失败组
    fail = []

    for i in range(1, len(sports), 2):
        # 序号大的运动员
        major = sports[i]
        # 序号小的运动员
        minor = sports[i-1]

        if major.strength > minor.strength:
            win.append(major)
            fail.append(minor)
        else:
            # 如果序号大的运动员的实力 <= 序号小的运动员,则序号小的运动员获胜
            win.append(minor)
            fail.append(major)

    # 如果晋级赛中运动员个数是奇数个,那么最后一个运动员直接晋级
    if len(sports) % 2 != 0:
        win.append(sports[-1])

    # 依次头部压入失败组,获胜组,保证头部是获胜组
    ans.insert(0, fail)
    ans.insert(0, win)

    # 如果保留组个数超过3个,那么需要将超过部分的组去掉,因为这部分人已经无缘季军
    while len(ans) > 3:
        ans.pop()


# 算法入口
def getResult():
    # ans只记录三个组,冠军组,亚军组,季军组
    ans = []

    # 晋级赛
    promote(sports, ans)

    # 冠军组如果不是一个人,那么还需要取出冠军组继续进行晋级赛
    while len(ans[0]) > 1:
        promote(ans.pop(0), ans)

    # 冠军
    first = ans[0][0].idx

    # 亚军
    second = ans[1][0].idx

    # 季军
    ans[2].sort(key=lambda x: (-x.strength, x.idx))
    third = ans[2][0].idx

    return f"{first} {second} {third}"


# 算法调用
print(getResult())import math

# 辗转相除法判断是否互质
def is_coprime(a, b):
    while b != 0:
        a, b = b, a % b
    return a == 1

# 判断是否相互互质
def are_coprime(a, b, c):
    return is_coprime(a, b) and is_coprime(a, c) and is_coprime(b, c)

def main():
    n = int(input())
    m = int(input())
    ans = []
    num = [0] * (m - n + 1)

    # 计算 n 到 m 之间每个数的平方
    for i in range(n, m + 1):
        num[i - n] = i * i

    s = set(num)  # 用集合去重

    # 寻找勾股数三元组
    for i in range(len(num)):
        for j in range(i + 1, len(num)):
            a_squared = num[i]
            b_squared = num[j]
            c_squared = a_squared + b_squared
            // 判断c^2是否是 [n,m]中整数的平方
            if c_squared not in s:
                continue
            c = int(math.sqrt(c_squared))
            // 判断是否互质
            if are_coprime(i + n, j + n, c):
                ans.append(f"{i + n} {j + n} {c}")

    # 输出结果
    if not ans:
        print("NA")
    else:
        for result in ans:
            print(result)

if __name__ == "__main__":
    main()


JavaScript

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  const sports = line
    .split(" ")
    .map(Number)
    .map((val, idx) => new Sport(idx, val));

  console.log(getResult(sports));
});

function getResult(sports) {
  // ans只记录三个组,依次是:冠军组,亚军组,季军组
  const ans = [];

  // 晋级赛
  promote(sports, ans);

  // 冠军组如果不是一个人,那么还需要取出冠军组继续进行晋级赛
  while (ans[0].length > 1) {
    promote(ans.shift(), ans);
  }

  // 冠军
  const first = ans[0][0].id;
  // 亚军
  const second = ans[1][0].id;

  // 季军
  ans[2].sort((a, b) =>
    a.strength != b.strength ? b.strength - a.strength : a.id - b.id
  );
  const third = ans[2][0].id;

  return `${first} ${second} ${third}`;
}

function promote(sports, ans) {
  // 记录获胜组
  const win = [];
  // 记录失败组
  const fail = [];

  for (let i = 1; i < sports.length; i += 2) {
    // 序号大的运动员
    const major = sports[i];
    // 序号小的运动员
    const minor = sports[i - 1];

    if (major.strength > minor.strength) {
      win.push(major);
      fail.push(minor);
    } else {
      // 如果序号大的运动员的实力 <= 序号小的运动员,则序号小的运动员获胜
      win.push(minor);
      fail.push(major);
    }
  }

  // 如果晋级赛中运动员个数是奇数个,那么最后一个运动员直接晋级
  if (sports.length % 2 != 0) {
    win.push(sports.at(-1));
  }

  // 依次头部压入失败组,获胜组,保证头部是获胜组
  ans.unshift(fail);
  ans.unshift(win);

  // 如果保留组个数超过3个,那么需要将超过部分的组去掉,因为这部分人已经无缘季军
  while (ans.length > 3) ans.pop();
}

class Sport {
  constructor(id, strength) {
    this.id = id; // 运动员的id
    this.strength = strength; // 运动员的实力
  }
}

Go

package main

import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)

// Sport 代表一个运动员,包含其 ID 和实力值
type Sport struct {
ID       int
Strength int64
}

// getResult 计算并返回冠军、亚军和季军的运动员 ID
func getResult(strengths []int64) string {
// ans 仅跟踪三个组:冠军组、亚军组、季军组
var ans [][]Sport

// 将输入的实力值转换为 Sport 对象
sports := make([]Sport, len(strengths))
for i, strength := range strengths {
sports[i] = Sport{ID: i, Strength: strength}
}

// 晋级赛
promote(sports, &ans)

// 继续晋级直到冠军组只剩下一个人
for len(ans[0]) > 1 {
firstGroup := ans[0]
ans = ans[1:] // 移除冠军组
promote(firstGroup, &ans)
}

// 冠军
first := ans[0][0].ID


// 亚军
second := ans[1][0].ID

// 对季军组按照实力降序排序,如果实力相同则按 ID 升序排序
sort.Slice(ans[2], func(i, j int) bool {
if ans[2][i].Strength != ans[2][j].Strength {
return ans[2][i].Strength > ans[2][j].Strength
}
return ans[2][i].ID < ans[2][j].ID
})
third := ans[2][0].ID

// 返回冠军、亚军和季军的 ID
return fmt.Sprintf("%d %d %d", first, second, third)
}

// promote 进行一轮晋级赛,将获胜组和失败组加入 ans
func promote(sports []Sport, ans *[][]Sport) {
// 获胜组
var win []Sport
// 失败组
var fail []Sport

// 按照比赛规则进行比较
for i := 1; i < len(sports); i += 2 {
major := sports[i]
minor := sports[i-1]

// 比较实力值
if major.Strength > minor.Strength {
win = append(win, major)
fail = append(fail, minor)
} else {
win = append(win, minor)
fail = append(fail, major)
}
}

// 处理奇数个运动员的情况
if len(sports)%2 != 0 {
win = append(win, sports[len(sports)-1])
}

// 将失败组和获胜组添加到 ans,确保获胜组在前
*ans = append([][]Sport{win, fail}, (*ans)...)


// 确保 ans 的大小不超过 3 个组
if len(*ans) > 3 {
*ans = (*ans)[:3]
}
}

func main() {
// 使用 bufio.Reader 来处理大输入
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("读取输入失败:", err)
return
}

// 解析输入
strengths := parseInput(input)

// 输出结果
fmt.Println(getResult(strengths))
}

// parseInput 将输入的字符串解析为实力值数组
func parseInput(input string) []int64 {
// 分割字符串
fields := strings.Fields(input)
strengths := make([]int64, len(fields))
for i, field := range fields {
val, err := strconv.ParseInt(field, 10, 64)
if err != nil {
fmt.Println("解析数字失败:", err)
return nil
}
strengths[i] = val
}
return strengths
}




原文地址:https://blog.csdn.net/qq_45776114/article/details/145271475

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!