CF1552D_Array Differentiation


1552D_Array Differentiation

思维:联想到图

/*
题意:给定序列 a 问能否构造出 b 使得 a 中每个数都可由 b 中数作差得到
将b数组看成点权,a数组看成边权,ai = bj - bk => j~k间有向边边权为ai,把作差理解成一条有向边
那么即得到一个 n 点 n 条边的图,若不考虑方向,这个图必然会有至少一个环
假设环上点为 b1 b2 b3 b4 ... bk => (b2 - b1) + (b3 - b2) + ... + (b1 - bk) = 0 
                               => t*a1 + t*a2 + ... + t*ak = 0 (t = 0/1/-1)
即暴力枚举是否存在a中的某些元素,+-随意组合结果为0即可
*/

// 实现上:t用三进制数表示每种情况,%3取当前位,/3右移

#include 

using namespace std;

void solve(){
    int sta = 1, n; cin >> n;
    
    std::vectora(n);
    for(int i = 0; i < n; ++i) cin >> a[i], sta *= 3;
    
    for(int i = 1; i < sta; ++i) {
        int sum = 0, t = i;
        for(int j = 0; j < n; ++j) {
            if(t % 3 == 1) sum += a[j];
            else if(t % 3 == 2) sum -= a[j];
            t /= 3;
        }
        if(!sum) {
            cout << "YES" << endl;
            return;
        }
    }
    
    cout << "NO" << endl;
}

int main()
{
    int T; cin >> T
    
    while(T--) {
        solve();
    }

    return 0;
}

相关