不开 O2 66 开 O2 79 救命
查看原帖
不开 O2 66 开 O2 79 救命
317198
MilkyCoffee楼主2021/6/13 09:53

不开 O2 是一个点 TLE 7 个 WA,开 O2 是 7 个 WA qwq

救命。。。

// jaco2567 AK IOI
// #include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

inline int read() {
    int res = 0, f = 1;
    char k;
    while (!isdigit(k = getchar())) if (k == '-') f = -1;
    while (isdigit(k)) {
        res = res * 10 + k - '0';
        k = getchar();
    }
    return res * f;
}

const int NR = 105;

int n, a[NR], sum, len;
bool vis[NR];

bool cmp(int x, int y) {
	return x > y;
}

bool dfs(int k, int last, int rest) {
	// a[k] | 当前木棒上的最后一根木棍 | 剩余长度
	if (k * len == sum) return 1;
	// k 根拼接好的木棍的长度是所有木棍的总长度
	if (rest == 0) {
		return dfs(k + 1, 1, len);
		// 还有下面一根
	}

	for (int i = last + 1; i <= n; i++) {
		if (vis[i] || rest < a[i]) continue ;
		vis[i] = 1;
		if (dfs(k, i, rest - a[i])) return 1;
		vis[i] = 0;

		// 第一根 / 最后一根木棒失败 特判
		if (rest == len || a[i] == rest) return 0;

		int j = i;
		while (j <= n && a[j] == a[i]) j++; // 同样长的
		i = j - 1;
	}

	return 0;
}

int main() {
	while (scanf("%d", &n) && n != 0) {
		memset(a, 0, sizeof(0));
		sum = 0;

		for (int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
			sum += a[i];
		}
		sort(a + 1, a + n + 1, cmp);

		// 从小到大穷举各种最终长度
		// 用 dfs 搜索。
		for (len = 2; len <= sum; len++) {
			if (sum % len != 0) continue ;

			memset(vis, 0, sizeof(vis));
			vis[1] = 1;
			if (dfs(1, 1, len)) {
				printf("%d\n", len);
				break ;
			}
		}

	}


    return 0;
}

2021/6/13 09:53
加载中...