CF1552 D. Array Differentiation
题意:
给出一个有n个数的数组a,能否构造出一个长为n的数组b,使a中的每个数都可以由b中某两个数相减得到。
令b[1]等于任意值,b[i]=a[i-1]+b[1],这样可以很容易的使a中的n-1个数满足要求
剩下一个数比较难搞
若b[x]-b[y]=a[i],在点x和点y之间连一条边权为a[1]的边
这样如果b满足要求,会得到一个n个点n条边的图
即图中必定由环
先看一个比较简单的例子,假设是3个数
a1=b1-b2
a2=b2-b3
a3=b3-b1
等号左侧、右侧分别相加,得到a1+a2+a3=b1-b2+b2-b3+b3-b1=0
如果是
a1=b1-b2
a2=b2-b3
a3=b1-b3
可以得到a1+a2-a3=0
继续推可以发现,若给ai带上正负号求和,那么这个环一定有一种方式求和为0
所以我们就可以枚举ai的符号(0,-1,1)求和
#include<bits/stdc++.h> using namespace std; int a[11]; int main() { int T,n,m,sum,s; bool tag; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); m=pow(3,n)-1; tag=false; for(int i=1;i<=m;++i) { s=i; sum=0; for(int j=1;j<=n;++j) { if(s%3==1) sum+=a[j]; else if(s%3==2) sum-=a[j]; s/=3; } if(!sum) { tag=true; break; } } puts(tag ? "YES" : "NO"); } }