Problem23

#include <iostream>
#include <vector>
#include <set>
#include <cmath>
using namespace std;

#define LIMIT 28123

void
aliquot(int n, set<int> *pset_pf)
{
    pset_pf->insert(1);
    if(n == 2)
    {
        return;
    }

    bool *t = new bool [n];
    memset(t, false, n);
    t[1] = true;

    for (int i = 2; i < n; i++)
    {
        if (n%i == 0 && !t[i])
        {
            t[i] = true;
            t[n/i] = true;
        }
        if (t[i])
        {
            pset_pf->insert(i);
            pset_pf->insert(n/i);
        }
    }

    delete [] t;
}

bool
isAbundant(int n)
{
    set<int> set_pf;
    aliquot(n, &set_pf);

    int sum = 0;
    for (set<int>::iterator it = set_pf.begin(), end = set_pf.end(); it != end; it++)
    {
        sum += *it;
    }
    
    return sum > n ? true : false;
}

int
main(int argc, char ** argv)
{
    int ans = 0;
    bool t_is[LIMIT];
    bool t_sum[LIMIT];
    memset(t_is, false, LIMIT);
    memset(t_sum, false, LIMIT);

    for (int n = 2; n < LIMIT; n++)
    {
        if (isAbundant(n))
        {
            t_is[n] = true;
        }
    }

    for (int i = 0; i < LIMIT; i++)
    {
        if (t_is[i])
        {
            for (int j = i; j+i < LIMIT; j++)
            {
                if (t_is[j])
                {
                    t_sum[i+j] = true;
                }
            }
        }
    }

    for(int i = 0; i < LIMIT; i++)
    {
        if (!t_sum[i])
        {
            ans += i;
        }
    }
    cout << ans << endl;

    return 0;
}

Problem22

#include <iostream>
#include <fstream>
#include <set>
#include <string>
using namespace std;

void
split(char *token, const char *delimit, set<string> *pv)
{
    char *tk;

    tk = strtok(token, delimit);

    while (tk != NULL) {
        pv->insert(tk);
        tk = strtok(NULL, delimit);
    }
}

void
split(string *token, const char *delimit, set<string> *pv)
{
    //  string を char に直す
    char *c = new char[token->size()];
    strcpy(c, token->c_str());

    split(c, delimit, pv);
}

int
score(string *s)
{
    int n = 0;

    for (string::iterator it = s->begin(), end = s->end(); it != end; it++)
    {
        n += *it - 'A' + 1;
    }

    return n;
}

int
main(int argc, char **argv)
{
    ifstream fin("names.txt");
    set<string> set_names;
    int ans = 0;
    string s;

    fin >> s;
    split(&s, "\",", &set_names);
    
    int i = 1;
    for(set<string>::iterator it = set_names.begin(), end = set_names.end(); it != end; it++)
    {
        string t = *it;
        ans += score(&t) * i++;
    }

    cout << ans << endl;

    return 0;
}

Problem21

#include <iostream>
#include <vector>
#include <set>
#include <cmath>
using namespace std;

#define NUM 10000

void
aliquot(int n, set<int> *pset_pf)
{
    pset_pf->insert(1);
    if(n == 2)
    {
        return;
    }

    bool *t = new bool [n];
    memset(t, false, n);
    t[1] = true;

    for (int i = 2; i < n; i++)
    {
        if (n%i == 0 && !t[i])
        {
            t[i] = true;
            t[n/i] = true;
        }
        if (t[i])
        {
            pset_pf->insert(i);
            pset_pf->insert(n/i);
        }
    }

    delete [] t;
}

int
pfSum(set<int> *pv_pf)
{
    int sum = 0;
    for (set<int>::iterator it = pv_pf->begin(), end = pv_pf->end(); it != end; it++)
    {
        sum += *it;
    }

    return sum;
}

int
main(int argc, char ** argv)
{
    int ans = 0;

    for (int n = 2; n < NUM; n++)
    {
        set<int> v_pf;
        aliquot(n, &v_pf);

        int sum = pfSum(&v_pf);
        if (n < sum && sum <= NUM)
        {
            set<int> v_tmp;
            aliquot(sum, &v_tmp);
            int tmpSum = pfSum(&v_tmp);

            if (tmpSum == n)
            {
                ans += n + sum;
            }
        }
    }

    cout << ans << endl;

    return 0;
}

Problem20

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

#define NUM 100

void
multi(string *ps, int num)
{
    string s("");
    int    c = 0;
    for (string::size_type i = ps->size(); i > 0; i--)
    {
        int n = (ps->at(i-1)-'0') * num + c;
        c = n/10;
        s += '0' + n%10;
    }
    if (c != 0)
    {
        while (c != 0)
        {
            s += '0' + (c%10);
            c /= 10;
        }
    }

    *ps = "";
    for (string::size_type i = 0; i < s.size(); i++)
    {
        *ps += s[s.size()-i-1];
    }
}

int
main(int argc, char **argv)
{
    string s = "1";
    int  ans = 0;

    for (int i = 2; i <= NUM ; i++)
    {
        multi(&s, i);
    }

    for (string::iterator it = s.begin(), end = s.end(); it != end; it++)
    {
        ans += *it - '0';
    }

    cout << ans << endl;

    return 0;
}

Problem19

#include <iostream>
using namespace std;

#define START 1901
#define END   2000

bool
isLeap(int y)
{
    if (y%4 != 0 || (y%100 == 0 && y%400 != 0))
    {
        return false;
    }
    else
    {
        return true;
    }
}

int
main(int argc, char **argv)
{
    int md[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int w = 1 + 365;
    int ans = 0;

    for (int y = START; y <= END; y++)
    {
        if (isLeap(y))
        {
            md[2] = 29;
        }
        else
        {
            md[2] = 28;
        }

        for (int m = 1; m <= 12; m++)
        {
            if (w%7 == 0)
            {
                ans++;
            }
            w += md[m];
        }
    }

    cout << ans << endl;

    return 0;
}

Problem18

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

#define NUM "\
75\n\
95 64\n\
17 47 82\n\
18 35 87 10\n\
20 04 82 47 65\n\
19 01 23 75 03 34\n\
88 02 77 73 07 63 67\n\
99 65 04 28 06 16 70 92\n\
41 41 26 56 83 40 80 70 33\n\
41 48 72 33 47 32 37 16 94 29\n\
53 71 44 65 25 43 91 52 97 51 14\n\
70 11 33 28 77 73 17 78 39 68 17 57\n\
91 71 52 38 17 14 91 43 58 50 27 29 48\n\
63 66 04 68 89 53 67 30 73 16 69 87 40 31\n\
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23"

int
main(int argc, char **argv)
{
    string s(NUM);
    istringstream is(s);
    vector<int> v;

    bool f = true;
    for (int l = 1, n = 0; f; l++)
    {
        v.resize(l);
        vector<int> v_tmp(v.size());
        for (int i = 0; i < l; i++)
        {
            if (is >> n)
            {
                if (l == 1)
                {
                    v_tmp[i] = n;
                }
                else
                {
                    if (i == 0)
                    {
                        v_tmp[i] = v[i]+n;
                    }
                    else if (i == l-1)
                    {
                        v_tmp[i] = v[i-1]+n;
                    }
                    else
                    {
                        if (v[i-1] > v[i])
                        {
                            v_tmp[i] = v[i-1]+n;
                        }
                        else
                        {
                            v_tmp[i] = v[i]+n;
                        }
                    }
                }
            }
            else
            {
                f = false;
            }
        }
        if (!f)
        {
            continue;
        }
        v.swap(v_tmp);
        for (int i = 0; i < l; i++)
        {
            cout << v[i] << " ";
        }
        cout << endl;
    }

    int max = -1;
    for (vector<int>::iterator it = v.begin(), end = v.end(); it != end; it++)
    {
        if (max < *it)
        {
            max = *it;
        }
    }
    cout << max << endl;

    return 0;
}