4893: 项链分赃
Time Limit: 4 Sec Memory Limit: 128 MB
Submit: 114 Solved: 75
[Submit][Status][Discuss]
Description
有一串长度为n的项链,上面有红绿蓝三种颜色的珠子,每种颜色的珠子数目都是偶数,现在要你把它切几刀分成
若干段,把其中一些段分给海盗1,剩余的段分给海盗2,要求两个海盗分得的每种颜色的珠子数量都相同,请输出
最少需要切多少刀。
Input
第一行一个整数n,表示项链的长度。
第二行n个0~2的整数,分别表示红绿蓝三种颜色。
Output
一行一个整数,为最少切多少刀。
Sample Input
6
0 2 2 1 0 1
Sample Output
2
样例解释:切两刀,分成{0,2},{2,1,0},{1}三份,第二份给海盗1,剩下给海盗2即可。
HINT
n<=100000
Source
By Monster_Yi
[Submit][Status][Discuss]
有个非常显然的结论。。。答案不超过3
任意取一种颜色考虑,设有 N 个
那么在这种颜色的第N/2 与 N/2+1 之间切一刀,然后分配一下就行了
其它两种颜色也类似,反正总能找到合适的方案
于是特判1刀或两刀的情形,剩下的就都是三刀了
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1E5 + 10;
int n,A[maxn],cnt[3],pre[maxn][3],suf[maxn][3];
inline int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint();
for (int i = 1; i <= n; i++) A[i] = getint();
for (int i = 1; i <= n; i++)
{
++cnt[A[i]];
for (int j = 0; j < 3; j++)
pre[i][j] = cnt[j];
}
for (int i = n; i; i--)
{
for (int j = 0; j < 3; j++)
suf[i][j] = suf[i + 1][j];
++suf[i][A[i]];
}
bool flag = 1;
for (int j = 0; j < 3; j++)
if (pre[n / 2][j] != cnt[j] / 2) flag = 0;
if (flag) {cout << 1 << endl; return 0;}
for (int i = 1; i < n / 2; i++)
{
int tmp; flag = 1;
for (int j = 0; j < 3; j++)
{
tmp = pre[i][j] + suf[n - (n / 2 - i) + 1][j];
if (tmp != cnt[j] / 2) {flag = 0; break;}
}
if (flag) {cout << 2 << endl; return 0;}
}
cout << 3 << endl;
return 0;
}