LoginSignup
1
0

More than 5 years have passed since last update.

第19回オフラインリアルタイムどう書くの参考問題をC++で解く

Posted at

思いついた解法のうち、短時間で実現可能そうなものを検討しているうちに1時間が経過してしまいました。
ハイゼンバグと、条件の勘違いに捕まって実装で2時間ほど。
合計3時間ほどかかりました。

最初に辞書を作っておいて、入力と突き合わせるという乱暴な方法をとっています。

お題はこちら

#include <iostream>
#include <sstream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iterator>
class Sanwa
{
public:
    static const int UPPER_LIMIT = 120;
    static const int u[][3];

    struct Element
    {
        int e1;
        int e2;
        int e3;
        Element(int e1, int e2, int e3) : e1(e1), e2(e2), e3(e3) {}
    };

    static Sanwa& get()
    {
        static Sanwa sanwa;
        return sanwa;
    }

    const std::vector<Element>& getElements() const
    {
        return elements_;
    }

    const std::vector<std::bitset<400> >& getValues() const
    {
        return values_;
    }

    static std::bitset<400> getValueSet(const Element& e)
    {
        std::bitset<400> result;
        for(int i = 0; i < 19; ++i)
        {
            result.set(e.e1 * u[i][0] + e.e2 * u[i][1] + e.e3 * u[i][2]);
        }
        return result;
    }

private:
    Sanwa()
    {
        for(int e1 = 1; e1 < UPPER_LIMIT; ++e1)
        {
            for(int e2 = e1 + 1; e2 < UPPER_LIMIT; ++e2)
            {
//                この条件要らなかった
//                if((e2 == e1*2) || (e2 == e1*3))
//                {
//                    continue;
//                }
                for(int e3 = e2 + 1; e3 < UPPER_LIMIT; ++e3)
                {
//                    この条件要らなかった
//                    if((e3 == e1*2) || (e3 == e1*3) || (e3 == e2*2) || (e3 == e2*3) || (e3  == e1+e2))
//                    {
//                        continue;
//                    }
                    Element e(e1, e2, e3);
                    elements_.push_back(e);
                    values_.push_back(getValueSet(e));
                }
            }
        }
    }

    Sanwa(const Sanwa&);
    Sanwa& operator = (const Sanwa&);

    std::vector<Element>           elements_;
    std::vector<std::bitset<400> > values_;
};

const int Sanwa::u[19][3] =
{
    { 0,0,1 }, { 0,1,0 }, { 1,0,0 },
    { 0,0,2 }, { 0,2,0 }, { 2,0,0 },
    { 0,1,1 }, { 1,0,1 }, { 1,1,0 },
    { 0,0,3 }, { 0,3,0 }, { 3,0,0 },
    { 0,1,2 }, { 1,0,2 }, { 1,2,0 },
    { 0,2,1 }, { 2,0,1 }, { 2,1,0 },
    { 1,1,1 }
};

std::ostream& operator << (std::ostream& out, const Sanwa::Element& e)
{
    return out << e.e1 << "," << e.e2 << "," << e.e3;
}

struct Includes
{
    const std::bitset<400>& source;

    Includes(const std::bitset<400>& source) : source(source) {}

    bool operator() (const std::bitset<400>& other) const
    {
        return (other & source) == source;
    }
};

static Sanwa& sanwa = Sanwa::get();

std::string solve(const std::string& s)
{
    std::bitset<400> source;
    std::istringstream iss(s);
    while(iss.good())
    {
        int i;
        char separator;
        iss >> i;
        source.set(i);
        iss >> separator;
    }

    std::vector<std::bitset<400> >::const_iterator i = std::find_if(sanwa.getValues().begin(), sanwa.getValues().end(), Includes(source));

    if(i == sanwa.getValues().end())
    {
        return "none";
    }

    if(std::find_if(std::next(i), sanwa.getValues().end(), Includes(source)) != sanwa.getValues().end())
    {
        return "many";
    }

    std::ostringstream oss;
    oss << sanwa.getElements()[std::distance(sanwa.getValues().begin(), i)];
    return oss.str();
}

void test(const std::string& source, const std::string& expected)
{
    std::cout << "source: " << source << ", expected: " << expected << std::flush;

    std::string actual = solve(source);

    if(expected == actual)
    {
        std::cout << " => o" << std::endl;
    }
    else
    {
        std::cout << ", actual: " << actual << " => x" << std::endl;
    }
}

int main(int, char* [])
{
    /*0*/ test( "3,11,12,102,111,120", "1,10,100" );
    /*1*/ test( "10,20,30,35,70", "many" );
    /*2*/ test( "1,5,20,80", "none" );
    /*3*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14", "many" );
    /*4*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", "1,4,5" );
    /*5*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,17", "none" );
    /*6*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,18", "1,4,6" );
    /*7*/ test( "5,6,7,8,9,10,11,12,13,14,15,16", "2,5,6" );
    /*8*/ test( "9,10,11,12,13,14,15,16,17,18,19", "4,5,7" );
    /*9*/ test( "11,36,37,45,55,70,71", "1,10,35" );
    /*10*/ test( "92,93,94,95,96,97,98,99", "30,32,33" );
    /*11*/ test( "95,96,97,98,99,100", "many" );
    /*12*/ test( "27,30,34,37,43,44,46,51,57", "10,17,23" );
    /*13*/ test( "6,10,13,17,65,73,76,80", "none" );
    /*14*/ test( "12,19,21,29,85", "none" );
    /*15*/ test( "1,2,8,10,14,23,58,62,64", "none" );
    /*16*/ test( "4,22,25,31,44,50,58,69,71,72,73,77", "none" );
    /*17*/ test( "8,16,26,27,42,53,65,69,81,83,88,99", "none" );
    /*18*/ test( "9,10,23,24,28,33,38,39,58,68,84", "none" );
    /*19*/ test( "11,16,24,26,88", "none" );
    /*20*/ test( "24,33,47,56,63,66,75,78,89,93", "none" );
    /*21*/ test( "7,26,72,77", "many" );
    /*22*/ test( "69,88,95,97", "many" );
    /*23*/ test( "9,14,48,89", "many" );
    /*24*/ test( "69,76,77,83", "many" );
    /*25*/ test( "11,14,24", "many" );
    /*26*/ test( "8,25,75,93", "many" );
    /*27*/ test( "11,55,93,98,99", "many" );
    /*28*/ test( "71,83,87", "many" );
    /*29*/ test( "22,76,77,92", "7,15,62" );
    /*30*/ test( "33,61,66,83,95", "17,33,61" );
    /*31*/ test( "6,16,49,55,72", "6,16,33" );
    /*32*/ test( "62,85,97,98", "12,25,73" );
    /*33*/ test( "54,60,67,70,72", "20,25,27" );
    /*34*/ test( "54,61,68,84,87", "27,30,34" );
    /*35*/ test( "65,67,69,75,79,89,99", "21,23,33" );
    /*36*/ test( "69,72,80,81,89", "23,24,33" );
    /*37*/ test( "1,2,3", "many" );

    return 0;
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0