存在
你可以进行两种操作:
输入保证有解,求一个合法操作方案。
这道题实际上是可以通过每个部分分来慢慢推出方案的。
首先第一档部分分,对于
然后考虑后面的
这时不难想到有如下方案:我们先将这张卡牌搁置,令其颜色为
如果
如果
然后这个时候我们可能会发现一点问题,比如如果有一个实际的结果:
思路看起来还是比较简单容易想的,但是这东西实现起来就能感受到恶心了,这里为了方便理解,大概说明一下代码中的部分关键变量名的作用。
对于每个 pair 前者表示栈的索引,后者为栈顶或栈底,ans 存的是答案,mp 指的是某个颜色对应的在栈中的位置,stk 存储的是对应位置中存的是什么颜色,mark 是指对应颜色被固定的位置(在遇到 unfix 存储的是所有空着的可以使用的栈的位置。
建议先做 T3 T4 再做这题
这个应该算是我写过最恶心的题之一了,调代码已经人调麻了。如果是在考场上我绝对部分分一拿就跑路。最开始有个思路然后写了一百多行写完了,调试的过程中发现假掉了。。。然后是参考的 @sssmzy 的思路,上面说的也是这个做法,然后做完就开始阴间调试的过程。最后本地对拍全过然后交上去就 WA,各种找样例各种手动模拟,不知道调了多久才找到问题:备用栈切换的时候 unfix 中可能有剩余的新栈中的空位,需要删除。
然后改来改去的代码可能变得很难看,敬请谅解,并且我的实现也可能不够精细,或许会有更简便的方法和更简便的实现,这里只是提供一个思路。还有个问题就是这个 erase 理论上最坏可能是
xxxxxxxxxx232123
45678910
11using namespace std;12
13mt19937 rnd(random_device{}());14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}15bool rnddd(int x){return rndd(1, 100) <= x;}16
17typedef unsigned int uint;18typedef unsigned long long unll;19typedef long long ll;20typedef long double ld;21
22template < typename T = int >23inline T read(void);24
25int N, M, K;26int a[2100000];27
28namespace Sub1{29 struct Ans{int flag; int a, b;};30 pair < int, bool > mp[610];31 int stk[310][2];32 basic_string < pair < int, bool > > unfix;33 basic_string < Ans > ans[2100000];34 void Make(void){35 memset(mp, 0, sizeof mp);36 memset(stk, 0, sizeof stk);37 for(int i = 1; i <= M; ++i)ans[i].clear(), ans[i].shrink_to_fit();38 unfix.clear();39 for(int i = N - 1; i >= 1; --i)unfix += {{i, 0}, {i, 1}};40 for(int i = 1; i <= M; ++i){41 int col(a[i]), cur(N);42 if(mp[col].first){43 if(mp[col].second){44 ans[i] += {Ans{1, cur}, Ans{2, mp[col].first, cur}};45 if(stk[mp[col].first][0])46 unfix += {mp[col].first, 0},47 mp[stk[mp[col].first][0]].second = 1;48 else49 unfix += {mp[col].first, 1};50 stk[mp[col].first][1] = stk[mp[col].first][0];51 stk[mp[col].first][0] = 0;52 mp[col] = {0, 0};53 }54 else{55 ans[i] += {Ans{1, mp[col].first}};56 unfix += mp[col];57 stk[mp[col].first][mp[col].second] = 0;58 mp[col] = {0, 0};59 }60 }else{61 if(!unfix.empty()){62 ans[i] += Ans{1, unfix.back().first};63 mp[a[i]] = unfix.back();64 stk[mp[col].first][mp[col].second] = col;65 unfix.pop_back();66 }else{67 printf("Error!\n"), exit(1);68 }69 }70 // printf("Finish %d\n", i);71 // printf("unfix: ");72 // for(auto tmpp : unfix)printf("(%d, %d) ", tmpp.first, tmpp.second ? 1 : 0);73 // printf("\n");74 // for(int i = 1; i <= 4; ++i)75 // printf("mp[%d] = %d, %d\n", i, mp[i].first, mp[i].second ? 1 : 0);76 }77 ll tot(0);78 for(int i = 1; i <= M; ++i)tot += ans[i].size();79 printf("%lld\n", tot);80 for(int i = 1; i <= M; ++i)81 for(auto opt : ans[i])82 if(opt.flag == 1)printf("1 %d\n", opt.a);83 else printf("2 %d %d\n", opt.a, opt.b);84 }85}86namespace Sub2{//1 - down, 0 - up87 struct Ans{int flag; int a, b;};88 basic_string < Ans > ans[2100000];89 pair < int, bool > mp[610];90 int cur(N);91 basic_string < pair < int, bool > > unfix;92 int stk[310][2];93 pair < int, bool > mark[610];94 void Make(void){95 for(int i = 1; i <= M; ++i)ans[i].clear(), ans[i].shrink_to_fit();96 memset(mp, 0, sizeof mp);97 memset(mark, 0, sizeof mark);98 memset(stk, 0, sizeof stk);99 cur = N, unfix.clear();100 for(int i = N - 1; i >= 1; --i)unfix += {{i, 0}, {i, 1}};101 for(int i = 1; i <= M; ++i){102 int col = a[i];103 if(mp[col].first){104 if(mp[col].second){105 ans[i] += {Ans{1, cur}, Ans{2, mp[col].first, cur}};106 if(stk[mp[col].first][0])107 unfix += {mp[col].first, 0},108 mp[stk[mp[col].first][0]].second = 1;109 else110 unfix += {mp[col].first, 1};111 stk[mp[col].first][1] = stk[mp[col].first][0];112 stk[mp[col].first][0] = 0;113 mp[col] = {0, 0};114 }115 else{116 ans[i] += {Ans{1, mp[col].first}};117 unfix += mp[col];118 stk[mp[col].first][mp[col].second] = 0;119 mp[col] = {0, 0};120 }121 }else{122 if(!unfix.empty()){123 ans[i] += Ans{1, unfix.back().first};124 mp[col] = unfix.back();125 stk[mp[col].first][mp[col].second] = col;126 unfix.pop_back();127 }else{128 int nxt;129 for(nxt = i + 1; nxt <= M; ++nxt){130 if(a[nxt] == col)break;131 // if(!ans[nxt].empty())continue;132 int ccol(a[nxt]);133 if(!mp[ccol].first){134 ans[nxt] += Ans{1, mark[ccol].first};135 unfix.erase(find(unfix.begin(), unfix.end(), mark[ccol]));136 mp[ccol] = mark[ccol];137 stk[mp[ccol].first][mp[ccol].second] = ccol;138 mark[ccol] = {0, 0};139 // if(!unfix.empty()){140 // ans[nxt] += Ans{1, unfix.back().first};141 // mp[ccol] = unfix.back();142 // stk[mp[ccol].first][mp[ccol].second] = ccol;143 // unfix.pop_back();144 // }else{145 // printf("Error\n"), exit(0);146 // }147 }else{148 if(!mp[ccol].second){149 mark[ccol] = mp[ccol];150 ans[nxt] += Ans{1, mp[ccol].first};151 unfix += mp[ccol];152 stk[mp[ccol].first][mp[ccol].second] = 0;153 mp[ccol] = {0, 0};154 }else{155 if(stk[mp[ccol].first][0]){156 ans[i] += Ans{1, mp[ccol].first};157 ans[nxt] += {Ans{1, cur}, Ans{2, mp[ccol].first, cur}};158 int stkpos = mp[ccol].first;159 mp[stk[mp[ccol].first][0]].second = 1;160 mp[col] = {mp[ccol].first, 0};161 mp[ccol] = {0, 0};162 stk[stkpos][1] = stk[stkpos][0];163 stk[stkpos][0] = col;164 break;165 }else{166 stk[mp[ccol].first][0] = 0;167 ans[i] += Ans{1, cur};168 ans[nxt] += Ans{1, mp[ccol].first};169 mp[col] = {cur, 1};170 unfix += {cur, 0};171 cur = mp[ccol].first;172 for(auto it = unfix.begin(); it != unfix.end();)173 if(it->first == cur)it = unfix.erase(it);174 else advance(it, 1);175 stk[mp[ccol].first][1] = 0;176 mp[ccol] = {0, 0};177 break;178 }179 }180 }181 }182 if(ans[i].empty()){183 ans[i] += Ans{1, cur};184 ans[nxt] += Ans{1, cur};185 }i = nxt;186 }187 }188 // printf("Finish %d\n", i);189 // printf("unfix: ");190 // for(auto tmpp : unfix)printf("(%d, %d) ", tmpp.first, tmpp.second ? 1 : 0);191 // printf("\n");192 // for(int i = 1; i <= 3; ++i)193 // printf("mp[%d] = %d, %d\n", i, mp[i].first, mp[i].second ? 1 : 0);194 }195 ll tot(0);196 for(int i = 1; i <= M; ++i)tot += ans[i].size();197 printf("%lld\n", tot);198 for(int i = 1; i <= M; ++i)199 for(auto opt : ans[i])200 if(opt.flag == 1)printf("1 %d\n", opt.a);201 else printf("2 %d %d\n", opt.a, opt.b);202 }203}204
205int main(){206 int T = read();207 while(T--){208 N = read(), M = read(), K = read();209 for(int i = 1; i <= M; ++i)a[i] = read();210 if(K == N * 2 - 2)Sub1::Make();211 else Sub2::Make();212 }213
214 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);215 return 0;216}217
218template < typename T >219inline T read(void){220 T ret(0);221 int flag(1);222 char c = getchar();223 while(c != '-' && !isdigit(c))c = getchar();224 if(c == '-')flag = -1, c = getchar();225 while(isdigit(c)){226 ret *= 10;227 ret += int(c - '0');228 c = getchar();229 }230 ret *= flag;231 return ret;232}update-2022_12_01 初稿