procon2019
このアカウントは京大マイコンクラブ(KMC)の2019年度の競技プログラミング練習会Normal(初心者向け)での説明用に作成したスライドです。 閲覧・参照はご自由にどうぞ。
第3回 ソート、二分探索、データ構造
担当:laft
bit.ly/2W5p7mT
KMC-ID:laft
あくまで一例ですが、下を参考に
配列長nとする。
index | 0 | 1 | 2 | 3 | 4 |
値 | 8 | 2 | 7 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 8 | 2 | 7 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 8 | 2 | 7 | 3 | 4 |
0番目>1番目なので入れ替え
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 8 | 7 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 8 | 7 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 8 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 8 | 3 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 8 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 8 | 4 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 4 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 4 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 4 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 7 | 3 | 4 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 3 | 7 | 4 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 3 | 4 | 7 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 3 | 4 | 7 | 8 |
3. これを最大n-1回繰り返す
index | 0 | 1 | 2 | 3 | 4 |
値 | 2 | 3 | 4 | 7 | 8 |
今回は3回目でソート済みとなった。
swap(a,b); :aとbの中身を入れ替えるSTL
//バブルソート
void bubble_sort(vector<int> &vec){
//n-1周全てを左から比較する。
for(int i=0;i<(int)vec.size()-1;++i){
//右端にできたソート済部分を除いて左から順に見る
for(int j=0;j<(int)vec.size()-i-1;++j){
//左>右なら
if(vec.at(j)>vec.at(j+1)) {
//右<左となるように入れ替える。
swap(vec.at(j),vec.at(j+1));
}
}
}
}
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 6 | 2 | 9 | 5 | 1 | 4 |
index | 0 | 1 | 2 |
値 | 6 | 2 | 9 |
index | 0 | 1 | 2 |
値 | 5 | 1 | 4 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 6 | 2 | 9 | 5 | 1 | 4 |
index | 0 | 1 | 2 |
値 | 6 | 2 | 9 |
index | 0 | 1 | 2 |
値 | 5 | 1 | 4 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 6 | 2 | 9 | 5 | 1 | 4 |
index | 0 | 1 | 2 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 6 | 2 | 9 | 5 | 1 | 4 |
index | 0 | 1 | 2 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 |
マージ後の配列
1の方が小さいので1を入れる。
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 |
マージ後の配列
1の方が小さいので1を入れる。
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 | 4 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 | 4 | 5 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 | 4 | 5 | 6 |
マージ後の配列
index | 0 | 1 | 2 | 3 |
値 | 2 | 6 | 9 |
index | 0 | 1 | 2 | 3 |
値 | 1 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 | 4 | 5 | 6 | 9 |
マージ後の配列
index | 0 | 1 | 2 | 3 | 4 | 5 |
値 | 1 | 2 | 4 | 5 | 6 | 9 |
マージ後の配列
index | 0 | 1 | 2 | 3 | 4 |
値 | 3 | 5 | 2 | 4 | 1 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 3 | 5 | 2 | 4 | 1 |
3より小さい配列
3より大きい配列
index | 0 | 1 | 2 | 3 | 4 |
値 | 3 | 5 | 2 | 4 | 1 |
2 | 1 |
5 | 4 |
3より小さい配列
3より大きい配列
index | 0 | 1 | 2 | 3 | 4 |
値 | 3 | 5 | 2 | 4 | 1 |
2 | 1 |
5 | 4 |
3より小さい配列
3より大きい配列
index | 0 | 1 | 2 | 3 | 4 |
値 | 3 | 5 | 2 | 4 | 1 |
1 | 2 |
4 | 5 |
3より小さい配列
3より大きい配列
3 |
1 | 2 |
4 | 5 |
3より小さい配列
3より大きい配列
基準値
index | 0 | 1 | 2 | 3 | 4 |
値 |
3 |
1 | 2 |
4 | 5 |
3より小さい配列
3より大きい配列
基準値
index | 0 | 1 | 2 | 3 | 4 |
値 | 1 | 2 | 3 | 4 | 5 |
index | 0 | 1 | 2 | 3 | 4 |
値 | 1 | 2 | 3 | 4 | 5 |
3 | 5 | 2 | 4 | 1 |
2 | 1 |
5 | 4 |
3 |
2 |
1 |
4 |
5 |
1 | 2 | 3 | 4 | 5 |
1 | 2 |
4 | 5 |
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
真ん中の値と比較する
2<7
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
真ん中の値と比較する
2<7
この区間には2はない
探索範囲
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2<3
探索範囲
この区間には2はない
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2<3
探索範囲
この区間には2はない
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 |
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2=2
発見!!
この区間には2はない
// v 中に t を見つけたら そのindex 、なければ -1を返す
int binsearch(vector<int> v, int t) {
int l = 0, r = v.size(); // 最初は全範囲 (半開区間)
while (l < r) { // 範囲の長さが 0 でない限り繰り返す
int m = l + (r - l) / 2; // 中間の点
// 中間点で一致した = 見つかった
if (v[m] == t) return m;
// 見つからなかったら、値の大小に応じて範囲を狭める
if (v[m] < t) l = m + 1;
else r = m;
}
// ここまできたら見つからなかった → v中にない
return -1;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
int n; cin >> n; //配列長nの宣言・入力
vector<int> v(n); //配列vの宣言
for(int i=0;i<n;++i){
cin >> v.at(i); //vの入力
}
sort(v.begin(),v.end()); //vの昇順ソート
int q; cin >> q; //クエリ数qの宣言・入力
for(int i=0;i<q;++i){
int x; cin >> x;//探索クエリxの宣言・入力
if(binary_search(v.begin(),v.end(),x)==1){
//二分探索して見つかったとき、"Yes"を出力。
cout << "Yes" << endl;
} else cout << "No" << endl; //なかったとき"No"を出力
}
}
全部STLにある!!!!
#include<bits/stdc++.h>
using namespace std;
int main(){
pair<int,int> pr; //pairを両方intで宣言
pr.first = 5; //1つ目に5を代入
pr.second = 3; //2つ目に3を代入
if(pr < make_pair(5,4)){ //(5,4)より小さいとき
//今回は実行される
//2番目の値を出力
cout << pr.second << endl; //3が出力される。
}
}
set<int> st = {5,1,3,2,4,6};
//beginから順番にイテレータを辿る。
//これによって、昇順ソートされたものと同等に出力できる。
//autoで初期化すれば、自動で型を決めてくれる。
for(auto itr = st.begin();itr!=st.end();++itr){
cout << *itr << endl; //*をつけて要素にアクセス。
//1,2,3,4,5,6が改行で区切られて出力される。
}
┏━━━━━━━━━━━┳━━┓
┃ c++ set ┃検索┃
┗━━━━━━━━━━━┻━━┛
By procon2019
発表日時 2019年4月26日(金)