NC206080. 完美的战役
描述
输入描述
输入包含多组数据,第一行包含一个数字 T(1 <= T <= 10) ,表示测试数据组数.接下来是 T 组数据,
每组数据第一行为两个整数 m, n(1 <= m,n <= 10) 分别表示 A、B 两个部落的分支数,
第二行包含 m 个整数 ,表示 A 部落每个分支的人数,
接下来 m 行,分别表示 A 部落第 i 个分支中第 j 个人的战力值为 ;
接下来一行包含 n 个整数 ,表示 B 部落每个分支的人数,
接下来 n 行,分别表示 B 部落第 i 个分支中第 j 个人的战力值为 。
输出描述
每组数据输出包含一行,如果一定能够出现完美的战役,输出 “YES” ,否则,输出 “NO” ,不含引号。
示例1
输入:
1 2 2 2 2 1 2 1 3 2 2 1 4 2 4
输出:
YES
说明:
A 部落 1 号分支中的组合为 (p11,p12),(p11),(p12) ,分别的战力值为 , , ,故该分支的战力值为 9;示例2
输入:
2 2 1 2 2 1 2 1 3 3 2 4 6 2 2 2 2 1 2 1 3 2 2 1 1 2 4
输出:
NO NO
C++11(clang++ 3.9) 解法, 执行用时: 204ms, 内存消耗: 3684K, 提交时间: 2020-05-23 17:58:55
#include<cstdio> long long bitA[200000], bitB[200000]; long long a[20], b[20]; void factor(long long u,long long bit[],long long offset){ int size = offset; while(u){ bit[size++] |= u%2; u /= 2; } } int main(){ int T; scanf("%d",&T); while(T--){ int n,m; scanf("%d%d",&n,&m); for(int i = 0; i <= 200000; i++) bitA[i] = bitB[i] = 0; for(int i = 0; i < n; i++) scanf("%lld",&a[i]); for(int i = 0; i < n; i++){ long long k = a[i]; long long sum = 0; for(int j = 0; j < k; j++){ long long u; scanf("%lld",&u); sum += u; } int offset = k-2; if(k==1) offset = 0, k = 0; long long mask = (k+1)*sum; factor(mask,bitA,offset); } for(int i = 0; i < m; i++) scanf("%lld",&b[i]); for(int i = 0; i < m; i++){ long long k = b[i]; long long sum = 0; for(int j = 0; j < k; j++){ long long u; scanf("%lld",&u); sum += u; } int offset = k-2; if(k==1) offset = 0, k = 0; long long mask = (k+1)*sum; factor(mask,bitB,offset); } int find = 0; for(int i = 0; i <= 200000; i++){ if(bitA[i] && !bitB[i]) find = 1; } if(!find) printf("YES\n"); else printf("NO\n"); } return 0; }
C++14(g++5.4) 解法, 执行用时: 133ms, 内存消耗: 616K, 提交时间: 2020-05-23 16:33:31
#include <iostream> #include <string> #include <vector> #include <cstring> using namespace std; const int maxn = 1e5 + 500; int sz[2]; bool isok[maxn][2]; int num[200][2]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while (T--) { memset(isok, 0, sizeof isok); cin >> sz[0] >> sz[1]; for (int cas = 0; cas <= 1; ++cas) { for (int i = 0; i < sz[cas]; ++i) { cin >> num[i][cas]; } for (int i = 0; i < sz[cas]; ++i) { int temp; int sum = 0; for (int j = 0; j < num[i][cas]; ++j) { cin >> temp; sum += temp; } int suffnum = num[i][cas] - 2; long long pre = 1ll * (num[i][cas] + 1) * sum; for (int j = 0; j < 60; ++j) { int bit = j + suffnum; if ((pre >> j) & 1) { isok[bit][cas] = true; } } } } int suc = 1; for (int i = 0; i < 1e5 + 300; ++i) { if (isok[i][0] && !isok[i][1]) { suc = 0; } } if (suc) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }