题目大意
题目大意
有 2n 张卡片排成一排,卡片上分别写着数字 1,1,2,2,…,n,n,初始时全部背面朝上。
你将使用以下“贪心”策略来进行翻牌游戏,每回合精确地翻开两张卡片:
-
如果你之前已经翻开过(且未被消除)两张数字相同的卡片,则直接翻开并消除它们。
-
否则,翻开从左到右第一张从未被翻开过的卡片,设其数字为 x。
-
接着,如果之前已经翻开过另一张数字为 x 的卡片,则翻开并消除它。
-
否则,再次翻开从左到右第一张从未被翻开过的卡片。如果这两张卡片数字相同,则消除;如果不同,则重新翻回背面。
给定 n 和 k,要求构造一个 1 到 n 各出现两次的排列,使得上述算法恰好需要 k 个回合才能消除所有卡片。如果存在这样的排列,输出 YES 并输出该排列;否则输出 NO。
输入格式
第一行包含一个整数 t(1≤t≤103),表示测试数据组数。
接下来每组数据包含一行,包含两个整数 n 和 k(1≤n≤3×105,1≤k≤106)。
保证所有测试数据中 n 的总和不超过 3×105。
输出格式
如果不存在满足条件的卡片排列,输出一行 NO。
如果存在,输出一行 YES,并在下一行输出 2n 个整数 a1,a2,…,a2n(1≤ai≤n),表示卡片上的数字排列。如果有多个合法的排列,输出任意一个即可。
样例输入
1 2 3 4 5 6 7
| 6 2 3 3 4 3 2 3 5 6 10 6 67
|
样例输出
1 2 3 4 5 6 7 8 9 10
| YES 2 1 2 1 YES 1 3 2 2 1 3 NO YES 1 2 3 1 2 3 YES 2 1 3 4 5 4 1 2 6 5 6 3 NO
|
样例解释
对于第一组样例,初始排列为 2 1 2 1,每回合的操作如下:
-
第 1 回合:翻开第一张未翻过的卡片(数字 2),之前没有记录,接着翻开下一张未翻过的卡片(数字 1)。数字不同,翻回背面。此时记下前两张卡片的数字为 2 和 1。
-
第 2 回合:翻开第一张未翻过的卡片(第三张,数字 2),由于之前已经翻开过数字为 2 的卡片(第一张),因此翻开第一张,两张卡片相同并消除。
-
第 3 回合:翻开第一张未翻过的卡片(第四张,数字 1),由于之前已经翻开过数字为 1 的卡片(第二张),因此翻开第二张,两张卡片相同并消除。
游戏结束,共花费 3 个回合。
对于第四组样例,初始排列为 1 2 3 1 2 3,每回合的操作如下:
-
第 1 回合:翻开第一、第二张从未翻过的卡片,数字分别为 1 和 2。数字不同,翻回背面。
-
第 2 回合:翻开第三、第四张从未翻过的卡片,数字分别为 3 和 1。数字不同,翻回背面。
-
第 3 回合:此时发现之前翻开过(且未消除)的卡片中存在两张数字相同的卡片(第一张和第四张均为 1),触发规则第一条,直接翻开这两张卡片并消除。
-
第 4 回合:没有两张已翻开且相同的卡片。翻开第五张卡片(数字 2),由于之前翻开过数字 2(第二张卡片),因此翻开第二张卡片并消除。
-
第 5 回合:翻开第六张卡片(数字 3),由于之前翻开过数字 3(第三张卡片),因此翻开第三张卡片并消除。
游戏结束,算法恰好在 k=5 回合赢得游戏。
注意啊,这是一个翻牌游戏,就是一开始你是不知道这些数字,它的大小,你需要翻开来你才知道。

思路讲解
这个题实在是太简单了,我操,哎呀,真的是后悔为什么没看这题。

不难发现,在这种位置交换一下,就会增加一次这个轮数,那么你就把所有的这些位置,就是你就交换他要求的这个轮数啊,当然是比N多的这个轮数然后就就好了。也就是把我们所找到的这个位置交换我们代码当中的REM次就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13
| ll rem=K-N; for (int cnt=1,i=2;cnt<=rem;++cnt,i+=2) { if (i>=N2) { cout<<"NO\n"; return; } swap(ans_ls[i],ans_ls[i+1]); } cout<<"YES\n"; for (int i=1;i<=N2;++i) { cout<<ans_ls[i]<<" "; } cout<<"\n";
|
AC代码
https://codeforces.com/contest/2202/submission/364156796
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include <bits/stdc++.h> #define all(vec) vec.begin(),vec.end() #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define debug(var) cerr << #var <<" = ["<<var<<"]"<<"\n"; #define debug1d(a) \ cerr << #a << " = ["; \ for (int i = 0; i < (int)(a).size(); i++) \ cerr << (i ? ", " : "") << a[i]; \ cerr << "]\n"; #define debug2d(a) \ cerr << #a << " = [\n"; \ for (int i = 0; i < (int)(a).size(); i++) \ { \ cerr << " ["; \ for (int j = 0; j < (int)(a[i]).size(); j++) \ cerr << (j ? ", " : "") << a[i][j]; \ cerr << "]\n"; \ } \ cerr << "]\n"; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x)
using namespace std;
using ll = long long; using ull = unsigned long long; using DB = double;
using CD = complex<double>;
static constexpr ll MAXN = (ll)1e6+10, INF = (1ll<<61)-1; static constexpr ll mod = 998244353; static constexpr double eps = 1e-8; const double pi = acos(-1.0);
ll lT,testcase;
void Solve() { ll N,K; cin >> N >> K; ll N2=2*N; vector<ll> ans_ls(N2+2); if (K<N) { cout<<"NO\n"; return; } if (K==N) { cout<<"YES\n"; for (int i=1,j=1;i<=N2;i+=2,j++) { cout<<j<<" "<<j<<" "; } cout<<"\n"; return; } for (int i=1,j=1;i<=N2;i+=2,j++) { ans_ls[i]=j; ans_ls[i+1]=j; } ll rem=K-N; for (int cnt=1,i=2;cnt<=rem;++cnt,i+=2) { if (i>=N2) { cout<<"NO\n"; return; } swap(ans_ls[i],ans_ls[i+1]); } cout<<"YES\n"; for (int i=1;i<=N2;++i) { cout<<ans_ls[i]<<" "; } cout<<"\n"; }
signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); #ifdef LOCAL cout.setf(ios::unitbuf); #endif
cin >> lT; for (testcase=1;testcase<=lT;++testcase) Solve(); return 0; }
|