能不能通过删除一些数字 使得数组a的一部分之和始终不能等于另一部分之和
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
const int N = 100 + 10, M = 200000 + 10;
int n, a[N], f[M];
int main()
{
cin>>n;
int sum = 0, vis = 0;
for(int i = 1; i <= n; i++)
{
cin>>a[i]; sum += a[i];
if(a[i] % 2) vis = i;
}
//cout<<sum<<'\n';
if(sum % 2) cout<<0;
else
{
int t = sum / 2;
for(int i = 1; i <= n; i++)
{
for(int j = t; j >= a[i]; j--)
{
f[j] = max(f[j], f[j - a[i]] + a[i]);
}
}
if(f[t] < t) cout<<0;//到底能不能取到 sum/2 能就删 不能就爬
else
{
if(vis) cout<<"1\n"<<vis;
else
{
int g = a[1];
for(int i = 2; i <= n; i++) g = __gcd(g, a[i]);
for(int i = 1; i <= n; i++)
{
a[i] /= g;
if(a[i] % 2) { cout<<"1\n"<<i; break; }
}
}
}
}
return 0;
}
还可以用lowbit()代替__gcd()
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
const int N = 100 + 10, M = 200000 + 10;
int n, a[N], f[M];
int lowbit(int x)
{
return x & -x;
}
int main()
{
cin>>n;
int sum = 0, vis = 0;
for(int i = 1; i <= n; i++)
{
cin>>a[i]; sum += a[i];
if(a[i] % 2) vis = i;
}
//cout<<sum<<'\n';
if(sum % 2) cout<<0;
else
{
int t = sum / 2;
for(int i = 1; i <= n; i++)
{
for(int j = t; j >= a[i]; j--)
{
f[j] = max(f[j], f[j - a[i]] + a[i]);
}
}
if(f[t] < t) cout<<0;
else
{
if(vis) cout<<"1\n"<<vis;
else
{
// int g = a[1];
// for(int i = 2; i <= n; i++) g = __gcd(g, a[i]);
// for(int i = 1; i <= n; i++)
// {
// a[i] /= g;
// if(a[i] % 2) { cout<<"1\n"<<i; break; }
// }
int mi = lowbit(a[1]);
for(int i = 2; i <= n; i++)
{
if(lowbit(a[i]) < mi) mi = lowbit(a[i]);
}
for(int i = 1; i <= n; i++)
{
a[i] /= mi;
if(a[i] % 2) { cout<<"1\n"<<i; break; }
}
}
}
}
return 0;
}
其实这题最精准的思路是,在确定全偶并且可以达到两边相同的情况下
把所有偶数同时缩小2的某次方倍,使得出现奇数,此时把奇数取出就足以打破平衡
比如:
本来两边情况为100 | 100
并且组成成分都是4的倍数
我们如果从左边拿一个12出来 右边无论如何都不可能拿出一个6来消弭差距 因为至少要是4的倍数
于是平衡被打破
所以最精确的思路是用lowbit把偶数们削成奇数
当然,gcd也可以达到此目的
就这么这一个赞,简直和我花在这题上的心思难以匹配
点了点了