Advertisement
Guest User

Version1

a guest
May 20th, 2019
533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.83 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <unordered_map>
  5.  
  6. using namespace std;
  7.  
  8. class Cube
  9. {
  10.     enum {TOP = 0, FRONT, RIGHT, BOTTOM, BACK, LEFT};
  11.     enum {_1 = 0, _2 = 1, _3 = 2, _4 = 3};
  12.  
  13. public:
  14.     using Type = unsigned int;
  15.  
  16.     Cube() : data{ "WWWW", "RRRR", "YYYY", "BBBB", "OOOO", "GGGG" } {} //"WWWW", "RRRR", "BBBB", "YYYY", "OOOO", "GGGG"
  17.  
  18.     Cube(const vector<string> &input)
  19.     {
  20.         data = input;
  21.     }
  22.  
  23.     Cube(const Cube &c) : data{ c.data }, repeat_cnt{ c.repeat_cnt }, path{ c.path } {}
  24.  
  25.     Cube(Cube &&c) : data{ move(c.data) }, repeat_cnt{ c.repeat_cnt }, path{ move(c.path) } {}
  26.  
  27.     const Cube& operator=(const Cube &c)
  28.     {
  29.         data = c.data;
  30.         path = c.path;
  31.  
  32.         return *this;
  33.     }
  34.  
  35.     const Cube& operator=(Cube &&c)
  36.     {
  37.         data = move(c.data);
  38.         path = move(c.path);
  39.  
  40.         return *this;
  41.     }
  42.  
  43.     friend ostream& operator<<(ostream &out, const Cube &c)
  44.     {
  45.         for (auto &x : c.data)
  46.             out << x << endl;
  47.  
  48.         return out;
  49.     }
  50.  
  51.     bool operator==(const Cube &c) const
  52.     {
  53.         static const vector<int> face{ TOP,FRONT,RIGHT,BOTTOM,BACK,LEFT };
  54.  
  55.         for (auto x : face)
  56.             if (to_uint(x) != c.to_uint(x))
  57.                 return false;
  58.        
  59.         return true;
  60.     }
  61.  
  62.     void flip(int i)
  63.     {
  64.         switch (i)
  65.         {
  66.         case 1:
  67.             L();
  68.             break;
  69.         case 2:
  70.             Lp();
  71.             break;
  72.         case 3:
  73.             U();
  74.             break;
  75.         case 4:
  76.             Up();
  77.             break;
  78.         case 5:
  79.             B();
  80.             break;
  81.         case 6:
  82.             Bp();
  83.             break;
  84.         default:
  85.             cout << "flip error" << endl;
  86.             break;
  87.         }
  88.  
  89.         add_path(i);
  90.     }
  91.  
  92.     Cube flip_cp(int i) const
  93.     {
  94.         Cube c{ *this };
  95.  
  96.         c.flip(i);
  97.  
  98.         return c;
  99.     }
  100.  
  101.     Type hash(void) const
  102.     {
  103.         vector<Type> n{ to_uint(0) ,to_uint(1) ,to_uint(2) ,to_uint(3) ,to_uint(4) ,to_uint(5) };
  104.  
  105.         return n[0] * 17 + n[1] * 11 + n[2] * 3 - n[3] * 7 + n[4] * 13 - n[5] * 19;
  106.     }
  107.  
  108.     void add_path(int i)
  109.     {
  110.         if (get_last_path() == i)
  111.             ++repeat_cnt;
  112.         else
  113.             repeat_cnt = 1;
  114.  
  115.         path += ('0' + i);
  116.     }
  117.  
  118.     int get_last_path(void) const
  119.     {
  120.         return path.empty() ? 0 : path[path.size() - 1] - '0';
  121.     }
  122.  
  123.     int get_cnt(void) const
  124.     {
  125.         return repeat_cnt;
  126.     }
  127.  
  128.     const string& get_path(void) const
  129.     {
  130.         return path;
  131.     }
  132.  
  133. private:
  134.    
  135.     vector<string> data;
  136.     int repeat_cnt;
  137.     string path;
  138.  
  139.  
  140.     Type to_uint(int idx) const
  141.     {
  142.         return *reinterpret_cast<const Type*>(data[idx].data());
  143.     }
  144.  
  145.     void L(void)
  146.     {
  147.         auto tem = data[LEFT][_1];
  148.  
  149.         // left
  150.         data[LEFT][_1] = data[LEFT][_3];
  151.         data[LEFT][_3] = data[LEFT][_4];
  152.         data[LEFT][_4] = data[LEFT][_2];
  153.         data[LEFT][_2] = tem;
  154.  
  155.         // top
  156.         tem = data[TOP][_1];
  157.         auto tem2 = data[TOP][_3];
  158.  
  159.         data[TOP][_1] = data[BACK][_4];
  160.         data[TOP][_3] = data[BACK][_2];
  161.  
  162.         // back
  163.         data[BACK][_4] = data[BOTTOM][_1];
  164.         data[BACK][_2] = data[BOTTOM][_3];
  165.  
  166.         // bottom
  167.         data[BOTTOM][_1] = data[FRONT][_1];
  168.         data[BOTTOM][_3] = data[FRONT][_3];
  169.  
  170.         // front
  171.         data[FRONT][_1] = tem;
  172.         data[FRONT][_3] = tem2;
  173.     }
  174.  
  175.     void Lp(void)
  176.     {
  177.         auto tem = data[LEFT][_1];
  178.  
  179.         // left
  180.         data[LEFT][_1] = data[LEFT][_2];
  181.         data[LEFT][_2] = data[LEFT][_4];
  182.         data[LEFT][_4] = data[LEFT][_3];
  183.         data[LEFT][_3] = tem;
  184.  
  185.         // top
  186.         tem = data[TOP][_1];
  187.         auto tem2 = data[TOP][_3];
  188.  
  189.         data[TOP][_1] = data[FRONT][_1];
  190.         data[TOP][_3] = data[FRONT][_3];
  191.  
  192.         // front
  193.         data[FRONT][_1] = data[BOTTOM][_1];
  194.         data[FRONT][_3] = data[BOTTOM][_3];
  195.  
  196.         // bottom
  197.         data[BOTTOM][_1] = data[BACK][_4];
  198.         data[BOTTOM][_3] = data[BACK][_2];
  199.  
  200.         // back
  201.         data[BACK][_4] = tem;
  202.         data[BACK][_2] = tem2;
  203.     }
  204.  
  205.     void U(void)
  206.     {
  207.         auto tem = data[TOP][_1];
  208.  
  209.         // top
  210.         data[TOP][_1] = data[TOP][_3];
  211.         data[TOP][_3] = data[TOP][_4];
  212.         data[TOP][_4] = data[TOP][_2];
  213.         data[TOP][_2] = tem;
  214.  
  215.         // front
  216.         tem = data[FRONT][_1];
  217.         auto tem2 = data[FRONT][_2];
  218.  
  219.         data[FRONT][_1] = data[RIGHT][_1];
  220.         data[FRONT][_2] = data[RIGHT][_2];
  221.  
  222.         // right
  223.         data[RIGHT][_1] = data[BACK][_1];
  224.         data[RIGHT][_2] = data[BACK][_2];
  225.  
  226.         // back
  227.         data[BACK][_1] = data[LEFT][_1];
  228.         data[BACK][_2] = data[LEFT][_2];
  229.  
  230.         // left
  231.         data[LEFT][_1] = tem;
  232.         data[LEFT][_2] = tem2;
  233.     }
  234.  
  235.     void Up(void)
  236.     {
  237.         auto tem = data[TOP][_1];
  238.  
  239.         // top
  240.         data[TOP][_1] = data[TOP][_2];
  241.         data[TOP][_2] = data[TOP][_4];
  242.         data[TOP][_4] = data[TOP][_3];
  243.         data[TOP][_3] = tem;
  244.  
  245.         // front
  246.         tem = data[FRONT][_1];
  247.         auto tem2 = data[FRONT][_2];
  248.  
  249.         data[FRONT][_1] = data[LEFT][_1];
  250.         data[FRONT][_2] = data[LEFT][_2];
  251.  
  252.         // left
  253.         data[LEFT][_1] = data[BACK][_1];
  254.         data[LEFT][_2] = data[BACK][_2];
  255.  
  256.         // back
  257.         data[BACK][_1] = data[RIGHT][_1];
  258.         data[BACK][_2] = data[RIGHT][_2];
  259.  
  260.         // right
  261.         data[RIGHT][_1] = tem;
  262.         data[RIGHT][_2] = tem2;
  263.  
  264.     }
  265.  
  266.     void B(void)
  267.     {
  268.         auto tem = data[BACK][_1];
  269.  
  270.         // back
  271.         data[BACK][_1] = data[BACK][_3];
  272.         data[BACK][_3] = data[BACK][_4];
  273.         data[BACK][_4] = data[BACK][_2];
  274.         data[BACK][_2] = tem;
  275.  
  276.         // top
  277.         tem = data[TOP][_1];
  278.         auto tem2 = data[TOP][_2];
  279.  
  280.         data[TOP][_1] = data[RIGHT][_2];
  281.         data[TOP][_2] = data[RIGHT][_4];
  282.  
  283.         // right
  284.         data[RIGHT][_2] = data[BOTTOM][_4];
  285.         data[RIGHT][_4] = data[BOTTOM][_3];
  286.  
  287.         // bottom
  288.         data[BOTTOM][_3] = data[LEFT][_1];
  289.         data[BOTTOM][_4] = data[LEFT][_3];
  290.  
  291.         // LEFT
  292.         data[LEFT][_1] = tem2;
  293.         data[LEFT][_3] = tem;
  294.     }
  295.  
  296.     void Bp(void)
  297.     {
  298.         auto tem = data[BACK][_1];
  299.  
  300.         // back
  301.         data[BACK][_1] = data[BACK][_2];
  302.         data[BACK][_2] = data[BACK][_4];
  303.         data[BACK][_4] = data[BACK][_3];
  304.         data[BACK][_3] = tem;
  305.  
  306.         // top
  307.         tem = data[TOP][_1];
  308.         auto tem2 = data[TOP][_2];
  309.  
  310.         data[TOP][_1] = data[LEFT][_3];
  311.         data[TOP][_2] = data[LEFT][_1];
  312.  
  313.         // LEFT
  314.         data[LEFT][_1] = data[BOTTOM][_3];
  315.         data[LEFT][_3] = data[BOTTOM][_4];
  316.  
  317.         // bottom
  318.         data[BOTTOM][_3] = data[RIGHT][_4];
  319.         data[BOTTOM][_4] = data[RIGHT][_2];
  320.  
  321.         // right
  322.         data[RIGHT][_2] = tem;
  323.         data[RIGHT][_4] = tem2;
  324.     }
  325. };
  326.  
  327.  
  328. class CubePermutation
  329. {
  330. public:
  331.     CubePermutation() : data(15)
  332.     {
  333.         vector<int> reserve_s{ 1,10,40,200,600,2500,9000,33500,114500,361000,931000,1351000,783000,91000,300 };
  334.  
  335.         for (int i = 0; i < data.size(); ++i)
  336.             data[i].reserve(reserve_s[i]);
  337.  
  338.         data[0].push_back(Cube{});
  339.        
  340.         mp.reserve(4000000);
  341.     }
  342.  
  343.     void run()
  344.     {
  345.         permutate();
  346.  
  347.         int t = 0;
  348.  
  349.         for (int i = 0; i < data.size(); ++i)
  350.         {
  351.            
  352.             cout << i << " size = " << data[i].size() << endl;
  353.  
  354.             t += data[i].size();
  355.         }
  356.  
  357.         cout << "total = " << t << endl;
  358.  
  359.     }
  360.  
  361.     int find(const vector<string> &input) const
  362.     {
  363.         Cube c{ input };
  364.  
  365.         auto key = c.hash();
  366.  
  367.         auto range = mp.equal_range(key);
  368.  
  369.         for(auto itr = range.first;itr != mp.end() && itr != range.second;++itr)
  370.             if (c == itr->second)
  371.             {
  372.                 auto ans = itr->second.get_path();
  373.  
  374.                 cout << "org setps : " << ans << endl;
  375.  
  376.                 for(auto i = ans.begin();i!=ans.end();++i)
  377.                     switch (*i)
  378.                     {
  379.                     case '1':
  380.                     case '2':
  381.                         *i = '2' - *i + '1';
  382.                         break;
  383.                     case '3':
  384.                     case '4':
  385.                         *i = '4' - *i + '3';
  386.                         break;
  387.                     case '5':
  388.                     case '6':
  389.                         *i = '6' - *i + '5';
  390.                         break;
  391.                     }
  392.  
  393.                 char ch;
  394.                 for (int i = 0, k = ans.size() - 1; i < k; ++i, --k)
  395.                 {
  396.                     ch = ans[i];
  397.                     ans[i] = ans[k];
  398.                     ans[k] = ch;
  399.                 }
  400.  
  401.  
  402.                 cout << "sol steps : " << ans << endl;
  403.                 return ans.size();
  404.             }
  405.  
  406.         return -1;
  407.     }
  408.  
  409. private:
  410.     enum { L = 1, Lp, U, Up, B, Bp };
  411.  
  412.     vector<vector<Cube>> data;
  413.     unordered_multimap<Cube::Type, Cube&> mp;
  414.  
  415.     void permutate(void)
  416.     {
  417.         int now, pre;
  418.         int i, k;
  419.  
  420.         for (now = 1; now <= 14; ++now)
  421.         {
  422.             pre = now - 1;
  423.            
  424.  
  425.             for (i = 0; i < data[pre].size(); ++i)
  426.             {
  427.                 for (k = 1; k <= 6; ++k)
  428.                 {
  429.                     if (is_redundant(pre, i, k))
  430.                         continue;
  431.  
  432.  
  433.                     data[now].emplace_back(data[pre][i].flip_cp(k));
  434.  
  435.                     check_exsited(now, data[now].size() - 1);
  436.                 }
  437.             }
  438.         }
  439.     }
  440.  
  441.     bool is_redundant(int pre, int idx, int now_step ) const
  442.     {
  443.         int last_step = data[pre][idx].get_last_path();
  444.         int m, M;
  445.  
  446.         if (now_step == last_step && ((last_step == Lp) || (last_step == Up) || (last_step == Bp)))
  447.             return true;
  448.  
  449.         if (now_step == last_step && data[pre][idx].get_cnt() == 2)
  450.             return true;
  451.  
  452.         if (last_step < now_step)
  453.         {
  454.             m = last_step;
  455.             M = now_step;
  456.         }
  457.         else
  458.         {
  459.             m = now_step;
  460.             M = last_step;
  461.         }
  462.  
  463.         if (M - m == 1 && (m & 0x01))
  464.             return true;
  465.  
  466.         return false;
  467.     }
  468.  
  469.     void check_exsited(int now, int idx)
  470.     {
  471.         auto key = data[now][idx].hash();
  472.  
  473.         auto range = mp.equal_range(key);
  474.         bool found = false;
  475.  
  476.         if (range.first != mp.end())
  477.             for (auto itr = range.first; itr != range.second; ++itr)
  478.                 if (itr->second == data[now][idx])
  479.                     found = true;
  480.  
  481.         if (found)
  482.             data[now].pop_back();
  483.         else
  484.             mp.emplace(key, data[now][idx]);
  485.     }
  486. };
  487.  
  488.  
  489. int main(void)
  490. {
  491.     CubePermutation p;
  492.  
  493.     p.run();
  494.    
  495.  
  496.     vector<string> input(6);
  497.  
  498.     while (true)
  499.     {
  500.         cout << "input:" << endl;
  501.  
  502.         for (int i = 0; i < 6; ++i)
  503.             getline(cin, input[i]);
  504.  
  505.         auto step = p.find(input);
  506.  
  507.         cout << "total " << step << endl;
  508.     }
  509.    
  510.  
  511.     cin.get();
  512.     return 0;
  513. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement