Codeforces Global Round 15_D. Array Differentiation

D. Array Differentiation

题目传送门:

题目传送门

题面:

在这里插入图片描述

题目大意:

给你大小为n的数组a,问是否存在大小相同的数组b,使得 a i = b m − b n a_i=b_m-b_n ai=bmbn对数组a中所有元素都成立。
输出YES/NO。

思路:

规律也是猜的,数组a里面有0,相反数,相同数;那么就变成(n)大小数组b构造(n-1)大小数组a,我假设一定可以直接输出YES,没证,感觉。
然后开头先对这个进行判断。
后面还有一点就是如果a中存在某个元素是另外两个元素的和,那么也化为(n)大小数组b构造(n-1)大小数组a,又是一个YES。
注意a中存在某个元素是另外两个元素的和,a中每个元素都有两种形态,即本身和相反数。
做法是全部放进去一起处理。

其实忘了考虑一点,a中某k个元素等于不同的p的元素的和好像也是可以的,没证明,有空再证。
如果这样的话就是样例水了给我混过去了。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
///C
//int a[500];
//int s[7];
//int vis[500];
//
//void init() {
//    memset(a, 0, sizeof(a));
//}
//
//int main() {
//    int T;
//    cin >> T;
//    while (T--) {
//        int n, k;
//        cin >> n >> k;
//        init();
//        int t1, t2;
//        for (int i = 0; i < k; i++) {
//            cin >> t1 >> t2;
//            a[t1] = t2;
//            a[t2] = t1;
//        }
//        int cnt = 0;
//        for (int i = 1; i <= n * 2; i++) {
//            if (!a[i]) vis[++cnt] = i;
//        }
//        int tmp = cnt / 2;
//        for (int i = 1; i <= tmp; i++) {
//            t1 = vis[i];
//            t2 = vis[i + tmp];
//            a[t1] = t2;
//            a[t2] = t1;
//        }
//        int ans = 0;
//        for (int i = 1; i <= 2 * n; i++) {
//            if (i <= a[i]) {
//                for (int j = 1; j < i; j++) {
//                    if (i != j && i != a[j]) {
//                        s[1] =(i > a[i])?a[i]:i;
//                        s[2] = (i < a[i])?a[i]:i;
//                        s[3] = (j > a[j])?a[j]:j;
//                        s[4] = (j < a[j])?a[j]:j;
//                        if (s[1] < s[3]) {
//                            if (s[2] > s[3] && s[2] < s[4])ans++;
//                        } else {
//                            if (s[4] > s[1] && s[4] < s[2])ans++;
//                        }
//                    }
//                }
//            }
//        }
//        cout << ans << endl;
//    }
//}


///D
int a[30];
int b[30];
set<int> s;
vector<int> v;

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin>>a[i];
            if (a[i] < 0)
                a[i] = -a[i];
        }
        sort(a, a + n);
        bool flag = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] == 0 || (i != 0 && a[i] == a[i - 1])) {
                flag = 1;
                break;
            }
            s.clear();
            for (int j = 0; j < n; j++) {
                if (j != i) {
                    v.clear();
                    for (auto x = s.begin(); x != s.end(); x++) {
                        int t = *x;
                        v.push_back(abs(t + a[j]));
                        v.push_back(abs(t - a[j]));
                    }
                    v.push_back(a[j]);
                    for (auto x = v.begin(); x != v.end(); x++) {
                        s.insert(*x);
                    }
                }
            }
            if (s.find(a[i]) != s.end()) {
                flag = 1;
                break;
            }
        }
        if (flag)
            cout << "YES" << endl;
        else
            cout << "No" << endl;
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值