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; }