LoginSignup
0
0

More than 3 years have passed since last update.

AtCoder ABC113 C - ID(300点)

Last updated at Posted at 2019-05-05

問題概要

$N$ 個の県と $M$ 個の都市がある。
市 $i$ は $Y_i$ 年の誕生し、 $P_i$ 県に属している。なお同じ年に生まれた市は存在しない。

市 $i$ が 県 $P_i$ に属する市の中で $x$ 番目に誕生した市のとき、市 $i$ の認識番号の上 $6$ 桁は $P_i$、下 $6$ 桁は $x$ となるような認識番号をそれぞれの市 $i$ に振り分ける。

全ての市の認識番号を求めよ。

制約条件

  • $1≤N≤10^5$
  • $1≤M≤10^5$
  • $1≤P_i≤N$
  • $1≤Y_i≤10^9$
  • $Y_i$ は全て異なる
  • 入力は全て整数

考えたこと

問題文をパット見でいいかんじにソートしたらよさそうと思った。

ではどうソートするかなのだが、認識番号は「所属する県」と「生まれた年」で構成される。所属する県はすでにわかっているが、その県の中でどれだけ古い県かは明らかになっていない。
よって年でソートして古い順に所属する県を数え上げていく。

あとは初めの市 $i$ の順番にソートしなおして出力。

考察よりも実装がめんどくさいなという問題。

多次元配列のソートのやり方は以下の記事を参照したらよい。
【C#】2次元配列(ジャグ配列・多次元配列)のソート

Array.Sort(array, (a, b) => a[1] - b[1]);  //昇順(index=1)

文字列を左詰めで出力する方法も忘れていたので調べた。以下の記事に詳しく書いてある。
- 書式指定文字列 (Format Strings)
- C#のstring.Formatで桁数や書式を指定する

String.Format("{0:D6}", i) //iは数字

解答

c.cs
using System;
using System.Linq;

class Program
{
    static void Main(string[] args) {
        int[] s = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int n = s[0];
        int m = s[1];
        int[][] l = new int[m][];
        for (int i = 0; i < m; i ++) {
            l[i] = new int[4];
            int[] a = Console.ReadLine().Split().Select(int.Parse).ToArray();
            l[i][0] = i;
            l[i][1] = a[0];
            l[i][2] = a[1];
        }
        Array.Sort(l, (a, b) => a[2] - b[2]);
        int[] c = new int[n];
        for(int i = 0; i < m; i ++) {
            c[l[i][1]-1] ++;
            l[i][3] = c[l[i][1]-1];
        }
        Array.Sort(l, (a, b) => a[0] - b[0]);
        for(int i = 0; i < m; i ++) {
            Console.WriteLine(String.Format("{0:D6}", l[i][1]) + String.Format("{0:D6}", l[i][3]));
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0