题目链接
https://nanti.jisuanke.com/t/19976
题意
给出 一个n 然后 给出 2*n 个数
可以重新排列成两行 然后 相邻的两个数 加起来 不能被三整除
可以上下相邻 也可以 左右相邻
思路
因为相加 根据同余定理 我们可以先把 每个数 模3
因为 可以重新排列 那么我们不妨 以最优的方式去排 看能不能得到 YES
很显然 , 0 和 0 1 和 2 不能放在一起
也就是说
0 要摆放的话 肯定是错位摆放的 比如这样
星号 表示 空位 那么很显然 0 的个数不能超过 n
那么我们可以知道 因为 1 和 2 不能在一起
那么 可以是这样
用 两个 0 形成一条分界线 上面放1 下面放2
然后可以知道 如果 只有两个 0 的话 那么很显然 只有当 1的个数 是奇数 并且 2 的个数 是偶数 才是成立的
还有一个比较显然的是
假如 只有1 或者 只有2 的话 那么在满足 0的个数 < n的情况下 是恒成立的
那么很显然 如果0 的个数 <= 1 并且同时存在 1 和 2 的话 那么 肯定存在至少一对(1, 2) 相邻
那只需要讨论 0 的个数 > 3 的情况了
先 讨论 0 的个数 == 3 的情况 如果 0 的个数 == 3 那么 就可以多出一个0 去弥补 空位
也就是说 可以存在 奇数1 偶数2 或者 奇数2 偶数1 的情况
那么也就是说 偶数1 偶数2 是不可行的
但实际上 不会存在这种情况 因为这种情况是 一奇两偶 相加是奇数 易知 数字总个数是2*n 必然为偶数
所以这种情况 不用考虑 也就是说 0的个数 == 3 并且 < n 的时候 是恒成立的
很显然 当0的个数 >= 4的时候 也满足
AC代码
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define pb push_back
#define fi first
#define se second
#define L(on) ((on)<<1)
#define R(on) (L(on) | 1)
#define mkp(a, b) make_pair(a, b)
#define bug puts("***bug***");
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define CLR(a, b) memset(a, (b), sizeof(a));
#define syn_close ios::sync_with_stdio(false); cin.tie(0);
#define sp system("pause");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector < vi > vvi;
const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;
inline int read()
{
char c = getchar(); int ans = 0, vis = 1;
while (c < '0' || c > '9') { if (c == '-') vis = -vis; c = getchar(); }
while (c >= '0' && c <= '9') { ans = ans * 10 + c - '0'; c = getchar(); }
return ans * vis;
}
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = (int)1e2 + 10;
const int MAXN = (int)1e4 + 10;
const ll MOD = (ll)1e9 + 7;
int n;
int arr[3];
void input()
{
n = read();
CLR(arr, 0);
for (int i = 0; i < 2 * n; i++)
arr[read() % 3]++;
}
bool solve()
{
if (arr[0] > n) return false;
if (arr[0] <= 1 && arr[1] && arr[2]) return false;
if (arr[0] == 2 && (arr[1] % 2 == 0) && (arr[2] % 2 == 0)) return false;
return true;
}
int main()
{
int t = read();
while (t--)
{
input();
puts(solve() ? "YES" : "NO");
}
}