桶排75分,题解1所有优化都加了,优化不动了。帮忙的大佬都能AK自己梦想的比赛。
评测记录 1WA 4TLE
代码如下,有注释:
#include <iostream>
using namespace std;
int ans;//存储所有数的和
int x;
int b[60], c[3000];//b数组存储下标出现几次,c数组存储所有约数
int ne[60], en[60];
int cnt, cc, dd;
bool tmp;
int dfs(int x, int y, int z, int c) { //需要拼成长是x的木棍,当前木棍还有y长度要拼,拼了z个,木棍从c开始搜索
if (tmp) return 1;
if (y == 0) {
if (x * z == ans) {
tmp = true;//标记不重复输出
cout << x;
return 1;
}
return dfs(x, x, z + 1, cc);
}
if (z == ans / x) {
tmp = true;//标记不重复输出
cout << x;
return 1;
}
int cd = min(c, y);
for (int i = cd; i >= dd; i = ne[i]) {
if (b[i] > 0) {
b[i]--;
if (b[i] == 0) {
ne[en[i]] = ne[i];
}
if (dfs(x, y - i, z, i))
return 1;
if (tmp) return 1;
ne[en[i]] = i;
b[i]++;
if (y == b[i] || y == x) return 0;
}
}
return 0;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {//输入求和
cin >> x;
b[x]++;
ans += x;
}
for (int i = 1; i <= ans; i++) {//找约数
if (ans % i == 0)
c[++cnt] = i;
}
for (int i = 50; i >= 1; i--) {//找最大
if (b[i] != 0) {
cc = i;
break;
}
}
for (int i = 1; i <= 50; i++) {//找最小
if (b[i] != 0) {
dd = i;
break;
}
}
int km = 0;
for (int i = 1; i <= 50; i++) {//链表预处理下一个数
ne[i] = km;
en[km] = i;
if (b[i] != 0) {
km = i;
}
}
for (int i = 1; i < cnt; i++) {//dfs求解
if (c[i] > cc) {
dfs(c[i], c[i], 1, cc);
if (tmp) return 0;
}
}
cout << c[cnt];
return 0;
}