サークルでバーチャルコンテストが行われ、その時「はえー便利だなー」ってなったことの備忘録です。
AtCoder ABC019 C問題を解いてる時、「setを使うと楽ですよ」と言われて、教えてもらいながら実装してみました。
問題はこちらです。
[blogcard url = "http://abc019.contest.atcoder.jp/tasks/abc019_3"] <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-more="more" data-wp-more-text="" class="wp-more-tag mce-wp-more" alt="" title="続きを読む..." data-mce-resize="false" data-mce-placeholder="1" /> 私の解答の方針は以下の通り <strong>「入力された数値を2で割り続け、割り切れなくなったところの数字を保存する。最後に保存された数字(重複除く)の数を数えて出力する」</strong> という単純作業の繰り返しでできます。 ここで面倒くさいのは、"保存された数字(重複除く)"という点です。 vectorに入れてた場合、sortしてuniqueで消していくという方法で重複をなくせるらしいです。 [blogcard url="https://qiita.com/ysk24ok/items/30ae72f4f1060b088588"] いろいろな方法がありますね・・・(vectorのuniqueとか知らなかった) 今回はsetを使って実装しました。 setとmapの特徴は以下の通り。 ・set はデータの追加・削除・検索の処理速度が O(log N) と高速 ・自動的にソートしてくれる mapとsetの違いについては、 setはキーのみを要素とするが、mapはpairを要素とする こと・・・らしいです。 [blogcard url="http://vivi.dyndns.org/tech/cpp/set.html"] [blogcard url="http://futurismo.biz/archives/1901"] 今回の解答の方針は以下の通りでした。「入力された数値を2で割り続け、割り切れなくなったところの数字を保存する。最後に保存された数字(重複除く)の数を数えて出力する」 この場合、setを使うと重複された数字は保存されずに済みます。 ということで、私が書いたコードは以下の通りになります。
[cpp]
#include &amp;amp;lt;iostream&amp;amp;gt;
#include &amp;amp;lt;set&amp;amp;gt;
using ll = long long;
using namespace std;
int main(int argc, char const *argv[]) {
int n;
cin&amp;amp;gt;&amp;amp;gt;n;
ll a[n];
for(int i=0;i&amp;amp;lt;n;i++) cin&amp;amp;gt;&amp;amp;gt;a[i];
set&amp;amp;lt;ll&amp;amp;gt; st;
for(int i=0;i&amp;amp;lt;n;i++){
while (a[i]%2!=1) {
a[i]=a[i]/2;
}
st.insert(a[i]);
}
cout&amp;amp;lt;&amp;amp;lt;st.size()&amp;amp;lt;&amp;amp;lt;endl;
return 0;
}
[/cpp]
このコード書いてる時、
[cpp] #define ll long long int [/cpp] って書くのめんどくさくない?って言ったら、clawさんが
[cpp] using ll = long long; [/cpp] って書き方を教えてくれました。C++11で追加されたらしいです。はえー。 まだまだ知らないこと多いなあと思った日でした。