質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

915閲覧

stable_sort()をしているのに安定ソートが出来ない

kay_ventris4

総合スコア269

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/07/17 17:23

編集2022/07/17 19:22

問題
ABC260 B問題

正解コード(Python3)
ソートの順番は、優先度の低いものから先にやっていくという方針です。

Python

1N, X, Y, Z = map(int, input().split()) 2A = list(map(int, input().split())) 3B = list(map(int, input().split())) 4 5ans = [] 6 7passed = {} 8for i in range(N): 9 passed[i + 1] = False 10 11score1 = [] 12for i in range(N): 13 score1.append([A[i], B[i], A[i] + B[i], i + 1]) 14score1.sort(key = lambda x: x[3], reverse = True) 15score1.sort(key = lambda x: x[0]) 16L1 = len(score1) 17for i in range(L1 - 1, L1 - X - 1, -1): 18 passed[score1[i][3]] = True 19 ans.append(score1[i][3]) 20 21score2 = [] 22for i in range(L1): 23 if passed[score1[i][3]] == False: 24 score2.append(score1[i]) 25score2.sort(key = lambda x: x[3], reverse = True) 26score2.sort(key = lambda x: x[1]) 27L2 = len(score2) 28for i in range(L2 - 1, L2 - Y - 1, -1): 29 passed[score2[i][3]] = True 30 ans.append(score2[i][3]) 31 32score3 = [] 33for i in range(L2): 34 if passed[score2[i][3]] == False: 35 score3.append(score2[i]) 36score3.sort(key = lambda x: x[3], reverse = True) 37score3.sort(key = lambda x: x[2]) 38L3 = len(score3) 39for i in range(L3 - 1, L3 - Z - 1, -1): 40 ans.append(score3[i][3]) 41 42ans.sort() 43for el in ans: 44 print(el)

不正解コード(C++17)
上のPythonのアルゴリズムと全く同じ方針でC++で行おうとしたものです。

C++

1#include <bits/stdc++.h> 2#include <math.h> 3using namespace std; 4#define ll long long 5 6/* import vector from standard input */ 7vector<ll> import_vector(ll n) { vector<ll> li; for (ll i = 0; i < n; i++) { ll j; cin >> j; li.push_back(j); } return li; } 8 9void solve() { 10 ll N, X, Y, Z; cin >> N >> X >> Y >> Z; 11 vector<ll> A = import_vector(N); 12 vector<ll> B = import_vector(N); 13 14 map<ll, bool> passed = {}; 15 for (ll i = 1; i < N + 1; i++) { 16 passed[i] = false; 17 } 18 19 vector<ll> ans = {}; 20 21 vector<vector<ll>> score1 = {}; 22 for (ll i = 0; i < N; i++) { 23 score1.push_back({A.at(i), B.at(i), A.at(i) + B.at(i), i + 1}); 24 } 25 26 sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[3] < beta[3];}); 27 reverse(score1.begin(), score1.end()); 28 sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[0] < beta[0];}); 29 ll L1 = score.size(); 30 for (ll i = L1 - 1; i >= L1 - X; i--) { 31 passed[score1.at(i).at(3)] = true; 32 ans.push_back(score1.at(i).at(3)); 33 } 34 35 vector<vector<ll>> score2 = {}; 36 for (ll i = 0; i < score.size(); i++) { 37 if (passed[score1.at(i).at(3)] == false) { 38 score2.push_back(score1.at(i)); 39 } 40 } 41 42 sort(score2.begin(), score2.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[3] < beta[3];}); 43 reverse(score2.begin(), score2.end()); 44 sort(score2.begin(), score2.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[1] < beta[1];}); 45 ll L2 = score2.size(); 46 for (ll i = L2 - 1; i >= L2 - Y; i--) { 47 passed[score2.at(i).at(3)] = true; 48 ans.push_back(score2.at(i).at(3)); 49 } 50 51 vector<vector<ll>> score3 = {}; 52 for (ll i = 0; i < score2.size(); i++) { 53 if (passed[score2.at(i).at(3)] == false) { 54 score3.push_back(score2.at(i)); 55 } 56 } 57 58 sort(score3.begin(), score3.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[3] < beta[3];}); 59 reverse(score3.begin(), score3.end()); 60 sort(score3.begin(), score3.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[2] < beta[2];}); 61 ll L3 = score3.size(); 62 for (ll i = L3 - 1; i >= L3 - Z; i--) { 63 ans.push_back(score3.at(i).at(3)); 64 } 65 66 sort(ans.begin(), ans.end()); 67 for (ll el: ans) { 68 cout << el << endl; 69 } 70} 71 72int main() { 73 solve(); 74}

改善策と質問
後者がうまくいかなかった理由として、C++のSTLで実装されるsort()が安定ソートではなく不安定ソートである為、ケースによっては受験者の番号の順序を保存したまま点数を並び替え出来ないからと推測しています。そうであるとした場合そこで、例えば

C++

1sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[3] < beta[3];}); 2reverse(score1.begin(), score1.end()); 3sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[0] < beta[0];});

C++

1stable_sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[3] < beta[3];}); 2reverse(score1.begin(), score1.end()); 3stable_sort(score1.begin(), score1.end(), [] (vector<ll> &alpha, vector<ll> &beta) {return alpha[0] < beta[0];});

としようとしたのですが、ラムダ関数をstable_sort()には使えないとコンパイルエラーが起きました。このような場合、どのようにすれば所望の出力を得られるのでしょうか。素人質問にて恐縮ですが、お力添え頂ける箇所が御座いましたら、ご教授のほど宜しくお願い申し上げます。

追記)このようにソート関数を自作しても同じテストケースで引っかかり駄目でした:

C++

1#include <bits/stdc++.h> 2#include <math.h> 3using namespace std; 4#define ll long long 5 6/* import vector from standard input */ 7vector<ll> import_vector(ll n) { vector<ll> li; for (ll i = 0; i < n; i++) { ll j; cin >> j; li.push_back(j); } return li; } 8 9/* sorted(li, key = lambda x: x[K], ascending = x) */ 10vector<vector<ll>> key_sort(vector<vector<ll>> li, ll K, bool x) { 11 vector<vector<ll>> ans = {}; 12 for (ll i = 0; i < li.size(); i++) { 13 ans.push_back(li.at(i)); 14 } 15 for (ll i = 0; i < ans.size(); i++) { 16 swap(ans.at(i).at(0), ans.at(i).at(K)); 17 } 18 if (!x) { 19 stable_sort(ans.begin(), ans.end()); 20 reverse(ans.begin(), ans.end()); 21 } 22 else { 23 stable_sort(ans.begin(), ans.end()); 24 } 25 26 for (ll i = 0; i < ans.size(); i++) { 27 swap(ans.at(i).at(0), ans.at(i).at(K)); 28 } 29 return ans; 30} 31 32void solve() { 33 ll N, X, Y, Z; cin >> N >> X >> Y >> Z; 34 vector<ll> A = import_vector(N); 35 vector<ll> B = import_vector(N); 36 37 vector<vector<ll>> score = {}; 38 for (ll i = 0; i < N; i++) { 39 score.push_back({A.at(i), B.at(i), A.at(i) + B.at(i), i + 1}); 40 } 41 42 map<ll, bool> passed = {}; 43 for (ll i = 1; i < N + 1; i++) { 44 passed[i] = false; 45 } 46 47 vector<ll> ans = {}; 48 49 score = key_sort(score, 3, false); 50 score = key_sort(score, 0, true); 51 52 for (vector<ll> el: score) { 53 show(el); 54 } 55 ll L1 = score.size(); 56 for (ll i = L1 - 1; i >= L1 - X; i--) { 57 passed[score.at(i).at(3)] = true; 58 ans.push_back(score.at(i).at(3)); 59 } 60 61 vector<vector<ll>> score2 = {}; 62 for (ll i = 0; i < score.size(); i++) { 63 if (passed[score.at(i).at(3)] == false) { 64 score2.push_back(score.at(i)); 65 } 66 } 67 68 score2 = key_sort(score2, 3, false); 69 score2 = key_sort(score2, 1, true); 70 ll L2 = score2.size(); 71 for (ll i = L2 - 1; i >= L2 - Y; i--) { 72 passed[score2.at(i).at(3)] = true; 73 ans.push_back(score2.at(i).at(3)); 74 } 75 76 vector<vector<ll>> score3 = {}; 77 for (ll i = 0; i < score2.size(); i++) { 78 if (passed[score2.at(i).at(3)] == false) { 79 score3.push_back(score2.at(i)); 80 } 81 } 82 83 score3 = key_sort(score3, 3, false); 84 score3 = key_sort(score3, 2, true); 85 ll L3 = score3.size(); 86 for (ll i = L3 - 1; i >= L3 - Z; i--) { 87 ans.push_back(score3.at(i).at(3)); 88 } 89 90 sort(ans.begin(), ans.end()); 91 for (ll el: ans) { 92 cout << el << endl; 93 } 94} 95 96int main() { 97 solve(); 98}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下のように修正すればコンパイルできます。
stable_sortの比較関数の引数は、Tconst T&しか受け付けないようです。

c++

1stable_sort(score1.begin(), score1.end(), [] (const vector<ll> &alpha, const vector<ll> &beta) {return alpha[3] < beta[3];}); 2reverse(score1.begin(), score1.end()); 3stable_sort(score1.begin(), score1.end(), [] (const vector<ll> &alpha, const vector<ll> &beta) {return alpha[0] < beta[0];});

投稿2022/07/17 20:53

actorbug

総合スコア2224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kay_ventris4

2022/07/18 03:19

正解しました・・・! ありがとうございます。そこにconst修飾子を付ければよかったんですね。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問