SRM464 ColorfulBoxesAndBalls

You are playing a game where you have numRed red boxes, numBlue blue boxes, numRed red balls, and numBlue blue balls.

You must place a single ball into each box. Each box is then scored as follows:
If the box is red and it contains a red ball, you get onlyRed points.
If the box is blue and it contains a blue ball, you get onlyBlue points.
In all other cases, you get bothColors points.
Your total score is the sum of the scores of all the boxes.

Return the maximum possible total score you can get.

#include <algorithm>
#include <limits.h>
using namespace std;

class ColorfulBoxesAndBalls {
    public:
        int getMaximum(int numRed, int numBlue, int onlyRed, int onlyBlue, int bothColors){
            int ans = INT_MIN;
            int change = min(numRed, numBlue);

            for(int i =0; i <= change; i++){
                int myscore = (numRed - i) * onlyRed
                    + (numBlue - i) * onlyBlue
                    + 2 * i * bothColors;
                ans = max(ans, myscore);
            }
            return ans;
        }
};

max値をfor文で回して、全パターンの最大値を検索するアルゴリズム
数が少ない方をchangeと定義するのがみそ

ニモニックコード

ニモニックコードも乱数に加えてチェックサムも入力される
BIP0039で定義されており、この乱数をエントロピーと呼ぶ

1. エントロピーを作成(乱数)
2. エントロピーに応じたチェックサムを生成
3. エントロピーとチェックサムを連結
4. 連結したデータを11ビットごとに分割
5. 11ビットで表現されている数字をインデックスとして、用意されている単語リストから単語を取得して空白区切りで連結

### ニモニックコードからシードを生成
シードの生成にはPBKDF2を利用
saltには定数”mnemoic”を使用し、2048回ストレッチングする
seed=hashlib.pbkdf2_hmac(‘sha512’, mnemonic, salt, 2048)
※パスフレーズを使用する際には、saltにパスフレーズを生成する

HD Wallet

privateKey * G = publicKey
(privateKey + i) * G = privateKey * G + i * G

i は推定不可能にするため、インデックスに加えて256ビットの巨大な乱数を1つ追加する
さらにハッシュ関数を適用する

乱数cとインデックスiを入力してハッシュ値をとったものをインデックス代わりに使用する
このインデックスと乱数を含んだハッシュ値をchain codeと呼ぶ

chain_code = h(i, c)

決定性ウォレットは最初の親秘密鍵と最初のチェーンコードだけをバックアップしておくだけで良い
最初の秘密鍵mはマスター秘密鍵、 M = mGはマスター公開鍵と呼ばれる
この二つの情報を生成するルールシードというデータを秘密情報の基点にしている。

マスターチェーンコード: mcc
インデックス: i=0, i=1,
インデックスiの子秘密鍵: priv0, …
インデックスiの子公開鍵: pub0, …
インデックスiのチェーンコードの左256ビット: cc0L, cc1L
インデックスiのチェーンコードの右256ビット: cc0R, cc1R

HMACとは暗号学的ハッシュ関数を使ったMAC
ビットコインではHMAC-SHA512のHMACが利用されている
マスターチェーンコードmccとマスター公開鍵M=mGからインデックスi=0の時のチェーンコードを計算し、その左256ビットを取り出す
このチェーンコードの左256ビットとマスター秘密鍵mの和がインデックスi=0の子秘密鍵になる。
iを0, 1, 2と変えることで、子秘密鍵・公開鍵を次々と作ることができる。

作成したチェーンコードの右側に256ビットのccRとインデックスからHMAC-SHA512からccL(左256ビット)と子秘密鍵で孫秘密鍵を作成できる
同様に子公開鍵から孫公開鍵を作ることもできる。

BadNeighbors 2004TCCC Online Round4

#include <vector>
using namespace std;

class BadNeighbors {
    public:
        int maxDonations(vector <int> donations) {
            int i;
            int ans = 0;

            int N = donations.size();
            int *dp = new int[N];

            for(i=0; i< N - 1; i++){
                dp[i] = donations[i];
                if(i > 0) dp[i] = max(dp[i], dp[i-1]);
                if (i>1) dp[i] = max(dp[i], dp[i-2] + donations[i]);
                ans = max(ans, dp[i]);
            }

            fo (i=0; i<N-1, i++){
                dp[i] = donations[i+1];
                if(i > 0) dp[i] = max(dp[i], dp[i-1]);
                if(i > 1) dp[i] = max(dp[i], dp[i-2] + donations[i+1]);
                ans = max(ans, dp[i]);
            }
            delete[] dp;
            return ans;
        }
}

SRM407 CorporationSalary

You are working in the HR department of a huge corporation. Each employee may have several direct managers and/or several direct subordinates. Of course, his subordinates may also have their own subordinates, and his direct managers may have their own managers. We say employee X is a boss of employee Y if there exists a sequence of employees A, B, …, D, such that X is the manager of A, A is the manager of B, and so on, and D is the manager of Y (of course, if X is a direct manager of employee Y, X will be a boss of employee Y). If A is a boss of B, then B can not be a boss of A. According to the new company policy, the salary of an employee with no subordinates is 1. If an employee has any subordinates, then his salary is equal to the sum of the salaries of his direct subordinates.

You will be given a String[] relations, where the j-th character of the i-th element is ‘Y’ if employee i is a direct manager of employee j, and ‘N’ otherwise. Return the sum of the salaries of all the employees.

#include <string>
#include <vector>
using namespace std;

long long salaries[50] = {0};

class CorporationSalary {
    public:
        long long totalSalary(vector <string> relations){
            long long total = 0;
            for (int i = 0; i < relations.size(); i++){
                total += getSalary(i, relations);
            }
            return total;
        }
        long long getSalary(int i, vector <string> relations) {
            if (salaries[i] == 0) {
                long long salary = 0;
                string relation = relations[i];

                for (int j = 0; j < relation.size(); j++){
                    if (relation[j] == 'Y') {
                        salary += getSalary(j, relations);
                    }
                }
                if (salary == 0) salary = 1;

                salaries[i] = salary;
            }
            return salaries[i];
        }
}

動的計画法

const int h = 5, w = 4;

int dfs(int nowh, int noww){
    if(nowh > h || noww > w) return 0;
    if(nowh == h && noww == w) return 1;
    return dfs(nowh + 1, noww) + dfs(nowh, noww + 1);
}
const int h = 5, w = 4;
int dp[h + 1, w + 1];

int dfs(int nowh, int noww){
    if (nowh > h || noww > w) return 0;
    if (nowh == h && noww == w) return 1;
    if (dp[nowh][noww] != 0) return dp[nowh][noww];
    return dp[nowh][noww] = dfs(nowh + 1, noww) + def(nowh, noww + 1);
}
const int h = 5, w = 4;
int dp[h + 1][w + 1];

void calc(){
    int i, j;
    dp[0][0] = 1;
    for(i=0; i<=h; i++) {
        for(j = 0; j<= w; j++){
            if (i != 0) dp[i][j] += dp[i - 1][j];
            if (j != 0) dp[i][j] += dp[i][j - 1];
        }
    }
}
int ws[5] = {3, 4, 1, 2, 3};
int ps[5] = {2, 3, 2, 3, 5};
int maxw = 10;

int ret = 0;

void knapsack(int n, int w, int p){
    if ( w > maxw) return;
    ret = max(ret, p);
    if(n >= 5) return;
    knapsack(n + 1, w, p);
    knapsack(n + 1, w + ws[n], p + ps[n]);
}
int ws[5] = {3, 4, 1, 2, 3};
int ps[5] = {2, 3, 2, 3, 5};
int maxw = 10;
int dp[6][11];
int ret = 0;

for(int i = 0; i <= 5; i++){
    for(int j = 0; j <= maxw; j++) {
        if(j + ws[i] <= maxw){
            dp[i + 1][j + ws[i]] =
                max(dp[i + 1][j + ws[i]], dp[i][j] + ps[i]);
                ret = max(dp[i + 1][j + ws[i]], ret);
        }
    }
}

計算量、メモリ使用量

void calc(){
    A();
    for(int i = 0; i < n; i++){
        B();
        for(int j = 0; j < m; j++){
            C();
        }
    }
}

素数計算

bool isPrime(int n){
    if(n < 2) return false;
    for(int i = 2; i * i <= n; i++){
        if(n % i == 0) return false;
    }
    return true;
}

logが含まれるもの

int bitcount(int n){
    int ret = 0;
    while(n > 0) {
        if (n % 2 == 1) ret++;
        n /= 2;
    }
    return ret;
}
int fibonacci(int n) {
    if(n==0) return 1;
    if(n==1) return 1;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

計算量の大きい関数

void calc(int n){
    for(int i = 0; i < n; i++) {
        fibonacci(n);
        for(int j=0; j < n; j++){
            isPrime(n);
            for(int k = 0; k < n; k++) {
                bitcount(n);
            }
        }
    }
}

SRM484 NumberMagicEasy

Taro shows a magic trick to Hanako.
Taro: Hello Hanako. I’ll show you a magic trick. Please imagine a positive integer less than or equal to 16.
Hanako: OK. I imagined it.
Taro: (Taro shows card 1 to Hanako.) Does this card contain your number?
Hanako: Yes.
Taro: (Taro shows card 2 to Hanako.) Does this card contain your number?
Hanako: No.
Taro: (Taro shows card 3 to Hanako.) Does this card contain your number?
Hanako: Yes.
Taro: (Taro shows card 4 to Hanako.) Does this card contain your number?
Hanako: Yes.
Taro: Your number is 5!

#include <string>
using namespace std;

class NumberMagicEasy {
    char Check(int x[], int number){
        for (int x=0; x<8; x++){
            if(X[x] == number) return 'Y';
        }
        return 'N';
    }
    public:
        int theNumber(string answer) {
            int A[] = {1, 2, 3, 4, 5, 6, 7, 8};
            int B[] = {1, 2, 3, 4, 9, 10, 11, 12};
            int C[] = {1, 2, 5, 6, 9, 10, 13, 14};
            int A[] = {1, 3, 5, 7, 9, 11, 13, 15};
            for (int i = 1; i <= 16; i++){
                if(Check(A, i) != answer[0]) continue;
                if(Check(B, i) != answer[0]) continue;
                if(Check(C, i) != answer[0]) continue;
                if(Check(D, i) != answer[0]) continue;
                return i;
            }
            return 0;
        }
}
class NumberMagicEasy {
    public:
        int theNumber(string answer){
            string c[] = {
                "YYYYYYYYNNNNNNNN",
                "YYYYNNNNYYYYNNNN",
                "YYNNYYNNYYNNYYNN",
                "YNYNYNYNYNYNYNYN",
            };
            for(int i=0; i<=15; i++){
                string temp="";
                for(int j=0; j<4; j++) temp += c[j][i];
                if(answer == temp) return i+1;
            }
        }
}

Ubuntuにbitcoin exploreをinstallしたい

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy

$ g++ –version
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ wget https://github.com/libbitcoin/libbitcoin-explorer/releases/download/v3.2.0/bx-linux-x64-qrcode
–2023-12-31 17:57:56– https://github.com/libbitcoin/libbitcoin-explorer/releases/download/v3.2.0/bx-linux-x64-qrcode
Resolving github.com (github.com)… 20.27.177.113
Connecting to github.com (github.com)|20.27.177.113|:443… connected.
HTTP request sent, awaiting response… 404 Not Found
2023-12-31 17:57:57 ERROR 404: Not Found.

bx seedで脆弱性があるのかDLできない…
v3.8.0のタグをDLする
https://github.com/libbitcoin/libbitcoin-explorer/releases
$ wget https://github.com/libbitcoin/libbitcoin-explorer/archive/refs/tags/v3.8.0.tar.gz
$ tar -xvf v3.8.0.tar.gz

$ sudo apt install g++-9
$ sudo ./install.sh –with-icu
//
/usr/bin/ld: cannot find libprotokit.a: No such file or directory
/usr/bin/ld: cannot find -llzma: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [Makefile:873: src/libbitcoin-protocol.la] Error 1

real 7m11.463s
user 11m48.472s
sys 1m7.459s

うーむ
$ wget https://github.com/libbitcoin/libbitcoin-explorer/archive/refs/tags/v3.2.0.tar.gz
$ tar -xvf v3.2.0.tar.gz
$ g++ –version
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
$ sudo apt-get install build-essential autoconf automake libtool pkg-config git
$ sudo apt-get install libboost-all-dev
$ cd libbitcoin-explorer-3.2.0
$ chmod +x install.sh
$ sudo apt install libsecp256k1-dev
$ sudo ./install.sh