トピックの説明
問題解決のアイデア
全体のアイデア:
- プロパティ: 各山の同じ数を達成するには、各山の石の数がすべての石の数を割ることができる必要があります。
- すべての石の数を合計し(合計)、最も大きな石の山の数を数えます。
- 結合できるのは和の因数のみであるため、和の因数は小さいものから大きいものまでたどることができます。
- 因子の正当性の判断: それぞれの山をたどってそれらを結合し、連続した石がその因子と同じになるように結合された場合は次の山を結合し続け、いくつかの連続した石がその因子より大きい場合は直接横断して次の因子を判断します。
コード
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int w[N];
// 检查因子是否合法
bool check(int cnt)
{
for (int i = 0, s = 0; i < n; i ++)
{
s += w[i];
if (s > cnt) return false;
if (s == cnt) s = 0;
}
return true;
}
int main()
{
int T;
cin >> T;
while (T --)
{
cin >> n;
int sum = 0;
for (int i = 0; i < n; i ++)
{
cin >> w[i];
sum += w[i];
}
for (int i = n; i; i --)
// sum / i 表示sum的一个因子
if (sum % i == 0 && check(sum / i))
{
cout << n - i << endl;
break;
}
}
return 0;
}