CodeForces977D Divide by three, multiply by two

题目

Polycarp likes to play with numbers. He takes some integer number xx, writes it down on the board, and then performs with it n−1n−1operations of the two kinds:

  • divide the number xx by 33 (xx must be divisible by 33);
  • multiply the number xx by 22.

After each operation, Polycarp writes down the result on the board and replaces xx by the result. So there will be nn numbers on the board after all.

You are given a sequence of length nn — the numbers that Polycarp wrote down. This sequence is given in arbitrary order, i.e. the order of the sequence can mismatch the order of the numbers written on the board.

Your problem is to rearrange (reorder) elements of this sequence in such a way that it can match possible Polycarp's game in the order of the numbers written on the board. I.e. each next number will be exactly two times of the previous number or exactly one third of previous number.

It is guaranteed that the answer exists.

Input

The first line of the input contatins an integer number nn (2≤n≤1002≤n≤100) — the number of the elements in the sequence. The second line of the input contains nn integer numbers a1,a2,…,ana1,a2,…,an (1≤ai≤3⋅10181≤ai≤3⋅1018) — rearranged (reordered) sequence that Polycarp can wrote down on the board.

Output

Print nn integer numbers — rearranged (reordered) input sequence that can be the sequence that Polycarp could write down on the board.

It is guaranteed that the answer exists.

Examples

input

6
4 8 6 3 12 9

output

9 3 6 12 4 8 

input

4
42 28 84 126

output

126 42 84 28 

input

2
1000000000000000000 3000000000000000000

output

3000000000000000000 1000000000000000000 

Note

In the first example the given sequence can be rearranged in the following way: [9,3,6,12,4,8][9,3,6,12,4,8]. It can match possible Polycarp's game which started with x=9x=9.

要点

  • 实际上就是深搜,我开始也没往这方面想,写出来才发现有点像那么回事= =
  • 将运算转换成了地图,然后在想如何减少这个反复搜索的耗时
  • 其实就是想用用Map和迭代器

自己家的代码

#include <iostream>
#include <map>
using namespace std;
enum Direction
{
    L, // 左除以2
    R, // 右乘以2
    U, // 上乘以3
    D, // 下除以3
    X  //初始
};
struct Status
{
    Direction dir;     //方向
    long long theNext; //下位数
    bool flag;         //是否走过
};

map<long long, Status> mapNum;

long long g_endPoint1 = 0, g_endPoint2 = 0;

void SearchNum(map<long long, Status>::iterator iterCurrent)
{
    long long keyNum = iterCurrent->first;
    Direction d = iterCurrent->second.dir;
    map<long long, Status>::iterator iterNext;

    int flag = 0;

    if (d != L && iterCurrent->first % 2 == 0)
    {
        iterNext = mapNum.find(keyNum / 2);
        if (iterNext != mapNum.end() && iterNext->second.flag == false)
        {
            flag++;
            iterNext->second.flag == true;
            iterNext->second.dir = R;
            iterNext->second.theNext = keyNum;
            SearchNum(iterNext);
        }
    }
    if (d != D && iterCurrent->first % 3 == 0)
    {
        iterNext = mapNum.find(keyNum / 3);
        if (iterNext != mapNum.end() && iterNext->second.flag == false)
        {
            flag++;
            iterNext->second.flag == true;
            iterNext->second.dir = U;
            iterCurrent->second.theNext = iterNext->first;
            SearchNum(iterNext);
        }
    }
    if (d != U)
    {
        iterNext = mapNum.find(keyNum * 3);
        if (iterNext != mapNum.end() && iterNext->second.flag == false)
        {
            flag++;
            iterNext->second.flag == true;
            iterNext->second.dir = D;
            iterNext->second.theNext = keyNum; //是我
            SearchNum(iterNext);
        }
    }
    if (d != R)
    {
        iterNext = mapNum.find(keyNum * 2);
        if (iterNext != mapNum.end() && iterNext->second.flag == false)
        {
            flag++;
            iterNext->second.flag == true;
            iterNext->second.dir = L;
            iterCurrent->second.theNext = iterNext->first;
            SearchNum(iterNext);
        }
    }

    if (flag == 0)
    {
        if (g_endPoint1 == 0)
            g_endPoint1 = keyNum;
        else
            g_endPoint2 = keyNum;
    }
}
int main()
{
    int n, i;
    cin >> n;
    long long t;
    for (i = 0; i < n; i++)
    {
        cin >> t;
        Status tStatus;
        tStatus.dir = X;
        tStatus.theNext = -1;
        tStatus.flag = false;
        mapNum[t] = tStatus;
    }
    // cout << mapNum.begin()->first;

    SearchNum(mapNum.begin());

    //判断究竟谁是开头
    if (g_endPoint1 == 0)
    {
        g_endPoint1 = mapNum.begin()->first;
    }
    long long temp = mapNum[g_endPoint1].theNext;

    if (temp == -1)
    {
        if (g_endPoint2 == 0)
        {
            g_endPoint2 = mapNum.begin()->first; //那么第一次搜索时就是开头的数字
        }
        g_endPoint1 = g_endPoint2;
    }

    while (true)
    {
        cout << g_endPoint1 << ' ';
        temp = mapNum[g_endPoint1].theNext;
        if (temp != -1)
        {
            g_endPoint1 = temp;
        }
        else
            break;
    }
    return 0;
}

p.s

  • 这次代码写得还真是。。。啰嗦
  • 之前还对网上的解题报告的寥寥几语感到不解与无奈,现在。。

  • 坚持下去吧

posted @ 2019-03-31 00:05  StarSpark0  阅读(...)  评论(... 编辑 收藏