桶排75分,优化不动了。帮忙的大佬都能AK自己梦想的比赛
  • 板块P1120 小木棍
  • 楼主retamian
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/9/17 12:08
  • 上次更新2023/11/2 19:50:07
查看原帖
桶排75分,优化不动了。帮忙的大佬都能AK自己梦想的比赛
1033360
retamian楼主2023/9/17 12:08

桶排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;
}
2023/9/17 12:08
加载中...