音乐厅有 A 和 B 两个入口。 每个入口按进入的先后记录了观众的入场时刻(秒)。 所以两份记录各自从小的时刻起依次排列(可能有多个相同的时刻)。 把两份记录合并,按入场时刻的顺序做成一份名单。 时刻相同时,A 入口的观众排在 B 入口的观众前面。 同一入口的观众保持原记录中的顺序。 名单最前面是 1 号。 第一行按 A 记录的顺序输出 A 入口观众们的名单编号,用一个空格隔开。 第二行按 B 记录的顺序,用同样的方式输出 B 入口观众们的名单编号。 输入第一行给出 A 记录的数量 n 和 B 记录的数量 m,第二行给出 A 的 n 个时刻,第三行给出 B 的 m 个时刻。
输入
1 ≤ n, m ≤ 10,000,0 ≤ 时刻 ≤ 1,000,000,000(整数)。 每行的时刻按不减的顺序给出
输出
两行:A 观众们的名单编号,B 观众们的名单编号
样例 1 · stdin
4 3
5 9 9 120
3 9 40
stdout
2 3 4 7
1 5 6
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
两份记录已经排好序,所以在每份记录上各放一根手指(位置 i、j),把较早的那位放进名单,只把那一边的手指移一格,n + m 步就结束。 时刻相同时 A 在前,所以选 A 的条件是 a[i] <= b[j]。 写成 < 的话,相同时刻 B 会先进去。 一份记录先用完时,另一份剩下的要全部接在后面。 只在 while (i < n && j < m) 时循环然后停下,就会漏掉尾巴,所以把条件写成 j == m || (i < n && a[i] <= b[j]),在一个循环里处理到底。 这时要先问 i < n,才不会读到已用完记录的范围外(&& 在前面为假时不看后面。 反过来写成 a[i] <= b[j] && i < n,Python、Java、C#、Craykon 会因越界错误停止)。 合在一起再排序也可以,但 JS/TS 的 sort() 没有比较函数时会转成字符串按字典序排,100 会排在 9 前面。 在 Java 中用 == 比较 List<Integer> 的两个值,比较的是是否同一个对象,所以 -128~127 以外的相同时刻会被判为不同。 放进 int[],或者用 equals、intValue()。 在一行中用空格连接输出数字时,Python print(*pos)、JS/TS/C# join(" ")、Craykon 控制台.输出(列表) 只在中间加空格,C、C++、Java 要自己注意不要在第一个数前面多出空格。
Pythonmain.py · 18 行
n, m = map(int, input().split())a = list(map(int, input().split()))b = list(map(int, input().split()))pos_a, pos_b = [], []i = j = 0place = 1while i < n or j < m: # A를 고르는 때: B가 다 끝났거나, A의 시각이 B보다 이르거나 같을 때(같으면 A가 먼저) if j == m or (i < n and a[i] <= b[j]): pos_a.append(place) i += 1 else: pos_b.append(place) j += 1 place += 1print(*pos_a)print(*pos_b)
JavaScriptmain.js · 17 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, m] = lines[0].trim().split(/\s+/).map(Number);const a = lines[1].trim().split(/\s+/).map(Number);const b = lines[2].trim().split(/\s+/).map(Number);const posA = [], posB = [];let i = 0, j = 0;for (let place = 1; place <= n + m; place++) { // B가 끝났거나 A가 이르거나 같으면 A가 먼저 if (j === m || (i < n && a[i] <= b[j])) { posA.push(place); i++; } else { posB.push(place); j++; }}console.log(posA.join(" ") + "\n" + posB.join(" "));
TypeScriptmain.ts · 17 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, m] = lines[0].trim().split(/\s+/).map(Number);const a: number[] = lines[1].trim().split(/\s+/).map(Number);const b: number[] = lines[2].trim().split(/\s+/).map(Number);const posA: number[] = [], posB: number[] = [];let i = 0, j = 0;for (let place = 1; place <= n + m; place++) { if (j === m || (i < n && a[i] <= b[j])) { posA.push(place); i++; } else { posB.push(place); j++; }}console.log(posA.join(" ") + "\n" + posB.join(" "));
JavaMain.java · 33 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { static int[] readInts(BufferedReader br, int k) throws Exception { StringTokenizer st = new StringTokenizer(br.readLine()); int[] r = new int[k]; for (int t = 0; t < k; t++) r[t] = Integer.parseInt(st.nextToken()); return r; } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int n = Integer.parseInt(st.nextToken()), m = Integer.parseInt(st.nextToken()); int[] a = readInts(br, n), b = readInts(br, m); // int[]라 ==가 값을 비교한다 StringBuilder outA = new StringBuilder(), outB = new StringBuilder(); int i = 0, j = 0; for (int place = 1; place <= n + m; place++) { if (j == m || (i < n && a[i] <= b[j])) { if (outA.length() > 0) outA.append(' '); outA.append(place); i++; } else { if (outB.length() > 0) outB.append(' '); outB.append(place); j++; } } System.out.print(outA + "\n" + outB + "\n"); }}
C#Main.cs · 31 行
using System;using System.Collections.Generic;class Program{ static void Main() { string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(first[0]), m = int.Parse(first[1]); int[] a = Array.ConvertAll(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries), int.Parse); int[] b = Array.ConvertAll(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries), int.Parse); var posA = new List<int>(n); var posB = new List<int>(m); int i = 0, j = 0; for (int place = 1; place <= n + m; place++) { if (j == m || (i < n && a[i] <= b[j])) { posA.Add(place); i++; } else { posB.Add(place); j++; } } Console.WriteLine(string.Join(" ", posA)); Console.WriteLine(string.Join(" ", posB)); }}
C++main.cpp · 30 行
#include <iostream>#include <vector>void printLine(const std::vector<int>& p) { for (size_t t = 0; t < p.size(); t++) std::cout << (t ? " " : "") << p[t]; std::cout << "\n";}int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, m; std::cin >> n >> m; std::vector<int> a(n), b(m); for (int& x : a) std::cin >> x; for (int& x : b) std::cin >> x; std::vector<int> posA, posB; int i = 0, j = 0; for (int place = 1; place <= n + m; place++) { if (j == m || (i < n && a[i] <= b[j])) { posA.push_back(place); i++; } else { posB.push_back(place); j++; } } printLine(posA); printLine(posB);}
Cmain.c · 28 行
#include <stdio.h>static int a[10000], b[10000];static int pos_a[10000], pos_b[10000];static void print_line(const int *p, int k) { for (int t = 0; t < k; t++) printf(t ? " %d" : "%d", p[t]); printf("\n");}int main(void) { int n, m; scanf("%d %d", &n, &m); for (int t = 0; t < n; t++) scanf("%d", &a[t]); for (int t = 0; t < m; t++) scanf("%d", &b[t]); int i = 0, j = 0; for (int place = 1; place <= n + m; place++) { /* B가 끝났거나 A가 이르거나 같으면 A가 먼저 */ if (j == m || (i < n && a[i] <= b[j])) { pos_a[i++] = place; } else { pos_b[j++] = place; } } print_line(pos_a, n); print_line(pos_b, m); return 0;}
Craykonmain.cray · 27 行
first = 控制台.读数字();n = first[0];m = first[1];a = 控制台.读数字();b = 控制台.读数字();posA = [];posB = [];i = 0;j = 0;循环 (place = 1; place <= n + m; place++){ // B가 끝났거나, A가 남아 있고 A의 시각이 이르거나 같으면 A가 먼저 // &&는 앞이 거짓이면 뒤를 보지 않으니 i < n을 먼저 묻는다 takeA = j == m || i < n && a[i] <= b[j]; 如果 (takeA) { posA.添加(place); i++; } 否则 { posB.添加(place); j++; }}控制台.输出(posA);控制台.输出(posB);