川のブログ

川の適当気ままなブログです。 

AOJ 0099 Surf Smelt Fishing Contest II

こんにちかわです。

久しぶりに解いていきたいと思います。

ソースコード

#include <bits/stdc++.h>
using namespace std;
int main(void){
    int n,event;
    cin>>n>>event;
    
    vector<int> possessionfish(n+1, 0);
    vector<int>::iterator iter;
    
    int index, topNum = -1;
    int fishing,num;
    
    for(;event>0;--event){
        cin>>num>>fishing;
        possessionfish[num]+=fishing;
        
        if(topNum == -1)topNum = num;
        else if(fishing > 0){
            if(possessionfish[num] > possessionfish[topNum] || (topNum > num && possessionfish[num] == possessionfish[topNum]))topNum = num;
        }else if(topNum == num){
            iter = max_element(possessionfish.begin(), possessionfish.end());
            index = distance(possessionfish.begin(), iter);
            topNum = index;
        }
        
        cout<<topNum<<" "<<possessionfish[topNum]<<endl;
    }
}

普通に解くだけなら

iter = max_element(possessionfish.begin(), possessionfish.end());
index = distance(possessionfish.begin(), iter);
topNum = index;

の部分だけでOKですが、

計算量を減らさないといけないため

Topの人のインデックスを保存しておき、

イベントごとの釣った数が正の場合は比較、

負の場合は上記の探し出すコードを利用しました。

リーダブルコードを読む part9

こんにちはかわです。

アドベントカレンダー24記事目です。

以下の続きです。

kawakawa.hatenablog.com

9章 変数と読みやすさ

  1. 変数が多いと変数を追跡するのが難しくなる。
  2. 変数のスコープが大きいとスコープを把握する時間が長くなる。
  3. 変数が頻繁に変更されると現在の値を把握するのが難しくなる。

1 変数を削除する

役に立たない一時変数

以下を満たしている確認する + 複雑な文を分割している + 明確になっている + 複数回使われている

中間結果を削除する

中間結果を保持するより、タスクを早く完了できないかを検討すべき。

制御フロー変数を削除する

doneのようなループのいろんなところにtrueがある変数

これは削除できる

また、 複雑なループ(ネストが何段もあるループ)はコードを

新しい関数に移すなどすべし。

2 変数のスコープを縮める

変数のことが見えるコード行数をできるだけ減らす。

→一度に考えなければいけない変数を減らせるから。

メンバ変数

メンバ変数はクラスの中で「ミニグローバル」になっていると言える。

「ミニグローバル」はできるだけ減らすべき。

staticにしたり、ローカル変数に格下げたりする。

大きなクラスを小さなクラスに分割するのも良い。

c++ のif文のスコープ

if文の条件式のためだけに使われている変数は

条件式の中で定義すればいい

JavaScriptで「プライベート」変数を作る

変数をクロージャで包むのもいい。

JavaScriptのグローバルスコープ

Javascriptはvarをつけないとグローバルスコープになってしまう

気をつける

PythonJavaScriptのネストしないスコープ

C++Javaのような言語にはブロックスコープがある。

しかしPythonJavaScriptは関数全体にこぼれ出る。

定義位置を下げる

使う直前に変数宣言をする。

3 変数は一度だけ書き込む

変数を操作する場所が増えると、現在値の判断が難しくなる

以上

リーダブルコードを読む part8

こんにちはかわです。

アドベントカレンダー23記事目です。

以下の続きです。

kawakawa.hatenablog.com

8章 巨大な式を分割

1 説明変数

if str.split('@')[0] == "kawa"

よりも

username = str.split('@')[0]
if username == "kawa"

のほうが何を書いているか分かりやすい

2 要約変数

user_owns_document = (request.user.id == document.owner.id)

if user_owns_document 
   #ユーザはこの文章を編集できる
end

if !user_owns_document 
    #文章は読み取り専用
end

3 ド・モルガンの法則を使う

適用できるか検討する

4 短絡評価の悪用

「頭がいい」コードに気をつける。
あとで他の人が読むときにわかりにくくなる。

ロジックを簡潔に落とし込むことがわかりにくさを生み出すことがある。

5 例:複雑なロジックと格闘する

ロジックが複雑になった場合は別の視点、逆の視点からも考える

単純なロジックにできないかを考える

6 巨大な分を分解する

DRY原則を意識しよう

qiita.com

7 式を簡潔にするもう一つの創造的な方法

メソッド名が似て同じことをしているような時はマクロを定義するのもよし

以上

kawakawa.hatenablog.com