0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

競技プログラミング練習記 No.49【ABC113練習】

0
Posted at

初回 -> はじめに

ABC113を解きました。
3完です!
D問題は難しくて解けていません。

問題 時間 アルゴリズム 実行時間
A 1min - 8ms
B 6min - 7ms
C 20min 座標圧縮 155ms

まとめ

先にまとめを載せます。これ自体は最後に書いてます。

C問題は座標圧縮です。解いた後に気付きましたw
入力値をソートする必要があるけれど出力時に入力の順番を使う場合は、
「ソート後の順番」→「入力の順番」に変換する用の変数を用意します。

これはchokudaiさんが記事で紹介している問題ですね。
→AtCoder(競技プログラミング)の色・ランクと実力評価、問題例
60minで解きましょうと紹介されているので、それより早く解けてうれしいです。

D問題むずかしかった。
あみだくじかー。あみだくじは実は代数学(群論)なんだよな。
「数学ガール ガロア理論」で勉強したからけっこう簡単に解けるだろうな。
って思っていたら全く解けませんでした。
動的計画法でした。代数学を使う解法はもっと数学的に複雑な問題を解く場合です。
問題の複雑さによって適切なツールを選択するスキルを身に着けたい。。。

A - Discount Fare

  int x, y;
  cin >> x >> y;
  cout << x + y / 2;

半額になるバスの運賃は2番目の入力でもらえるので、1番目の入力と2番目入力の半分を足したものが答えになります。

B - Palace

  int n, t, a, h;
  cin >> n >> t >> a;
  int ans = 0;
  double ans_t = 1e9;
  for(int i = 0; i < n; ++i)
  {
    cin >> h;
    double temp = abs(a - (t - h * 0.006));
    if (temp < ans_t)
    {
      ans_t = temp;
      ans = i + 1;
    }
  }
  cout << ans;

「各地点の平均気温」は入力をもらった時にわかりますね。
(過去や未来の入力値に影響しません。)
そのため、入力をもらうたびに逐次処理しています。
abs(a - (t - h * 0.006))で「平均気温との差」がわかるので、これが最小になるものが答えです。
整数ではなく実数なので型に注意です。

C - ID

using P = pair<ll, ll>;

  ll n, m, p, y;
  cin >> n >> m;
  vector<P> a(m);
  map<P, int> ump;
  map<int, map<int, P> > mp;
  for(int i = 0; i < m; ++i)
  {
    cin >> p >> y;
    P ind = P(p, y);
    a[i] = ind;
    ump[ind] = i;
    mp[p][y] = ind;
  }

  for(const auto& ip : mp)
  {
    int ind = 1;
    for(const auto& im : ip.second)
    {
      a[ump[im.second]].second = ind;
      ind++;
    }
  }

  cout << setfill('0') << right;
  for(const auto& city : a)
  {
    cout << setw(6) << city.first << setw(6) << city.second << endl;
  }

座標圧縮という処理をする問題です。
与えられた数値を、大小関係を保ったまま小さい数字に直します。
[10,5,7,3,2] -> [5,3,4,2,1]というような操作になります。

この問題は、都市番号ごとに分けた後、誕生年でソートします。
ソート後の順番を使ってIDを生成し、元の入力順に出力します。
この「ソート後の順番」→「元の入力順」の変換が複雑でした。
std::mapは自動でソートをしてくれることを利用しました。

map[県番号][誕生年] = 「入力のPair」 となるstd::mapと、
map[入力のPair] = 「入力順」 となる変換用のstd::mapを用意すると、この問題は解けます。
tupleを使うと変数を減らせるのですが、慣れていないので使いませんでした。

以上です。ありがとうございました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?