517_CSP-S_%你赛2_赛后总结

穿精又带淫゛_ 提交于 2019-11-29 11:21:26

A题,考试的时候花了90min左右终于想出一个接近正解的办法(而然大佬都是一眼扫出结果),发现每个数分解都是log(n)完成并且有效的子因子始终只有两个,所以可以开map记录每个数分解的情况,

/* A - 木棍 */
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int MAXN = 51;
int n, a[MAXN], anss = MAXN * 30;

struct rec
{
    int num, sum;
};

map<int, int> ans, mp;
priority_queue<rec> q;

bool operator<(const rec &a, const rec &b)
{
    return a.sum > b.sum;
}

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch))
        f = (ch == '-') ? -1 : 1, ch = getchar();
    while (isdigit(ch))
        x = x * 10 + (ch - '0'), ch = getchar();
    return x * f;
}

void bfs(int now, int i)
{
    rec x;
    x.num = now;
    x.sum = 1;
    q.push(x);
    while (!q.empty())
    {
        x = q.top();
        q.pop();
        if (mp[(x.num)] != 0)
            continue;
        mp[x.num] = x.sum;
        if (x.num == 1)
            continue;
        if (x.num % 2 == 0)
            q.push((rec){x.num / 2, x.sum + 1});
        else
            q.push((rec){x.num / 2, x.sum + 1}), q.push((rec){x.num / 2 + 1, x.sum + 1});
    }
    map<int, int>::iterator iter;
    for (iter = mp.begin(); iter != mp.end(); iter++)
    {
        if (ans[iter->first] == 0 && i != 1)
            mp[iter->first] = 0;
        else
            mp[iter->first] += ans[iter->first];
    }
    ans.clear();
    for (iter = mp.begin(); iter != mp.end(); iter++)
        if (iter->second != 0)
            ans[iter->first] = iter->second /*,printf("%d %d\n",iter->first,iter->second)*/;
}

main()
{
    n = read();
    ;
    for (int i = 1; i <= n; ++i)
    {
        a[i] = read();
        mp.clear();
        bfs(a[i], i);
    }
    map<int, int>::iterator it;
    for (it = ans.begin(); it != ans.end(); it++)
        anss = min(anss, it->second);
    printf("%d", anss - n);
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!