20210716模拟
两个构造+一个数据结构,两个构造没有一个给checker的……
这场考试我很有毅力的洋洋洒洒写了一共可能有400行代码
T1
正解是个具有一定正确性的乱搞……好吧
这里就讲一讲我的29分做法
首先硬币太多了,不好考虑,我就想按照一定规律来消除这些硬币,强制选取前两个,并在对应的等差数列的位置再选一个
这样我会从左往右把这些硬币推过去,但是我又思考可能左边一个都推不了,那么很简单,我从左到右,从右到左各做一遍就好了
那么这样子做完最后会变成什么情况呢?
最后剩下的硬币的数量一定\(\leq 2\)
证明:如果一边推不了,说明中间的长度>len/2,那么这些推不了的位置互相之间的距离一定是<len/2的,我们可以从另一边推
这样剩下的点一定互相都推不了,长度有上限,最多只有两个点
零个点直接输出方案
现在问题就简化成两个点和一个点怎么消除了,我还是不满足,全变成一个点怎么做?
如果两个点之间可以形成等差数列,直接把两个点变成一个点,如果不能,我们可以两次翻转把一边的点往内撤,变成可以形成等差数列
好,现在全都只剩一个点了,然后我就构造出了一种对于所有的一个点如何消除的方案,光荣的得到了29分的好成绩
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define B cout<<"Breakpoint"<<endl;
#define O(x) cout<<#x<<" "<<x<<endl;
#define o(x) cout<<#x<<" "<<x<<" ";
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 5e5+10;
char a[maxn];int b[maxn],cnt,s[maxn];
priority_queue<int> q,q1;
bool vis[maxn];
int pos,step[maxn][4],ans;
void solve(int n){
int lst;bool flag = 0;
for (int i = 1;i <= n;i++){
if (s[i] == 1){
if (!flag) lst = i,flag ^= 1;
else{
if (i*2-lst > n) break;
flag ^= 1,step[++ans][0] = lst,step[ans][1] = i,step[ans][2] = i*2-lst,s[i*2-lst] ^= 1,s[i] ^= 1,s[lst] ^= 1;
}
}
}
flag = 0;
for (int i = n;i >= 1;i--){
if (s[i] == 1){
if (!flag) lst = i,flag ^= 1;
else{
if (i*2-lst < 1) break;
// cout<<lst<<" "<<i<<endl;
flag ^= 1,step[++ans][0] = i*2-lst,step[ans][1] = i,step[ans][2] = lst,s[i*2-lst] ^= 1,s[i] ^= 1,s[lst] ^= 1;
}
}
}
for (int i = n;i >= 1;i--) if (s[i] == 1) b[++cnt] = i;
}
int main(){
freopen("coin.in","r",stdin);
freopen("coin.out","w",stdout);
scanf ("%s",a+1);
int len = strlen(a+1);
for (int i = 1;i <= len;i++) s[i] = a[i]-'0';
solve(len);
if (cnt == 0){
printf("%d\n",ans);
for (int i = 1;i <= ans;i++) printf("%d %d %d\n",step[i][0],step[i][1],step[i][2]);
return 0;
}
// cout<<b[1]<<" "<<b[2]<<endl;
if (cnt == 2){
if (b[1]-b[2] == 3){
step[++ans][0] = b[2],step[ans][1] = b[2]+1,step[ans][2] = b[2]+2;
step[++ans][0] = b[2]+1,step[ans][1] = b[2]+2,step[ans][2] = b[1];
printf("%d\n",ans);
for (int i = 1;i <= ans;i++) printf("%d %d %d\n",step[i][0],step[i][1],step[i][2]);
return 0;
}
else{
if ((b[1]-b[2])&1){
step[++ans][0] = b[2],step[ans][1] = (b[1]+b[2] >> 1),step[ans][2] = b[1];
pos = (b[1]+b[2] >> 1);
}
else{
step[++ans][0] = b[1]-2,step[ans][1] = b[1]-1,step[ans][2] = b[1];
step[++ans][0] = b[1]-3,step[ans][1] = b[1]-2,step[ans][2] = b[1]-1;
step[++ans][0] = b[2],step[ans][1] = ((b[1]-3+b[2]) >> 1),step[ans][2] = b[1]-3;
pos = ((b[1]-3+b[2]) >> 1);
}
}
}
if (cnt == 1) pos = b[1];
while (len-pos < 15){
step[++ans][0] = pos-2,step[ans][1] = pos-1,step[ans][2] = pos;
step[++ans][0] = pos-3,step[ans][1] = pos-2,step[ans][2] = pos-1;
// o(pos) o(step[ans][0]) o(step[ans][1]) O(step[ans][2])
pos = pos-3;
}
// cout<<pos<<endl;
step[++ans][0] = pos+2,step[ans][1] = pos+3,step[ans][2] = pos+4;
step[++ans][0] = pos+3,step[ans][1] = pos+6,step[ans][2] = pos+9;
step[++ans][0] = pos+5,step[ans][1] = pos+7,step[ans][2] = pos+9;
step[++ans][0] = pos+5,step[ans][1] = pos+6,step[ans][2] = pos+7;
step[++ans][0] = pos,step[ans][1] = pos+2,step[ans][2] = pos+4;
printf("%d\n",ans);
for (int i = 1;i <= ans;i++) printf("%d %d %d\n",step[i][0],step[i][1],step[i][2]);
return 0;
}
/*
00000000000000000000000000001010000
10101010101001111010101000101010101
*/
T2
分块题,不怎么会,明天补
T3
首先对于m = 1和\(x_i \leq 2\)有很显然的构造方式
然后我把目光看向了\(n\leq 3,m\leq 9\),暴力打了个表……,真的是纯在打表
最后看\(x_i\geq 2\)的情况,其实不光是这个情况,越长的铜线越不好往里添加,我们需要1和2来补齐
如果我一条直线添加,中间拐上去的线,除了1和2,或者一个长铜线的头,其他条件都不会覆盖他
那1和2我补哪里都行,而且如果我把另一个长铜线的头和他拼在一起中间的部分只能用1解决了,而这里没有1,所以我要不不直线添加,要不就2补齐
如果我不直线添加,我这么拐弯呢?我发现我拐完之后,相当于在直线添加的情况两头加了墙,实际是一样的
所以我们选择直线添加,用2补齐,其实都挺简单的,就是我表打的比较长……233行
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define B cout<<"Breakpoint"<<endl;
#define O(x) cout<<#x<<" "<<x<<endl;
#define o(x) cout<<#x<<" "<<x<<" ";
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 1e5+10;
int n,m;
struct node{
int id,val;
}x[maxn];
int ans[5][maxn];
bool cmp(node x,node y){
return x.val < y.val;
}
void subtask1(){
if (n == 1) printf("yes\n1\n1\n1\n");
else printf("no\n");
}
void subtask2(){
int cnt1 = 0,cnt2 = 0,cnt3 = 0,t = 1;
for (int i = m;i >= 1;i--){
if (x[i].val == 2&&cnt1 < n) ans[1][++cnt1] = x[i].id,ans[2][++cnt2] = x[i].id;
else if (x[i].val == 2) ans[3][++cnt3] = x[i].id,ans[3][++cnt3] = x[i].id;
else {
if (cnt1 < n) {ans[1][++cnt1] = x[i].id;continue;}
if (cnt2 < n) {ans[2][++cnt2] = x[i].id;continue;}
if (cnt3 < n) {ans[3][++cnt3] = x[i].id;continue;}
}
}
printf("yes\n");
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++) printf("%d ",ans[i][j]);
puts("");
}
}
void subtask3(){
if (n == 2){
if (m == 2){
if (x[2].val == 5){
ans[1][1] = ans[1][2] = ans[2][1] = ans[2][2] = ans[3][1] = x[2].id,ans[3][2] = x[1].id;
}
if (x[2].val == 4){
ans[1][1] = ans[1][2] = ans[2][1] = ans[3][1] = x[2].id,ans[2][2] = ans[3][2] = x[1].id;
}
if (x[2].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[2].id,ans[1][2] = ans[2][2] = ans[3][2] = x[1].id;
}
}
if (m == 3){
if (x[3].val == 4){
ans[1][1] = ans[2][1] = ans[2][2] = ans[3][1] = x[3].id,ans[1][2] = x[2].id,ans[3][2] = x[1].id;
}
if (x[3].val == 3){
ans[1][2] = ans[2][2] = ans[3][2] = x[3].id,ans[1][1] = ans[2][1] = x[2].id,ans[3][1] = x[1].id;
}
}
if (m == 4){
if (x[4].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[4].id,ans[1][2] = x[3].id,ans[2][2] = x[2].id,ans[3][2] = x[1].id;
}
}
}
if (n == 3){
if (m == 2) {printf("no\n");return;}
if (m == 3){
if (x[3].val == 7){
ans[1][1] = ans[1][2] = ans[1][3] = ans[2][1] = ans[2][3] = ans[3][1] = ans[3][2] = x[3].id,ans[2][2] = x[2].id,ans[3][3] = x[1].id;
}
if (x[3].val == 6){
ans[1][1] = ans[1][2] = ans[1][3] = ans[2][1] = ans[2][2] = ans[3][1] = x[3].id,ans[2][3] = ans[3][2] = x[2].id,ans[3][3] = x[1].id;
}
if (x[3].val == 5){
ans[1][1] = ans[1][2] = ans[2][1] = ans[2][2] = ans[3][1] = x[3].id,ans[3][2] = x[1].id,ans[1][3] = ans[2][3] = ans[3][3] = x[2].id;
}
if (x[3].val == 4&&x[2].val == 4){
ans[1][1] = ans[2][1] = ans[3][1] = ans[3][2] = x[3].id,ans[1][2] = ans[2][2] = ans[2][3] = ans[3][3] = x[2].id,ans[1][3] = x[1].id;
}
if (x[3].val == 4&&x[2].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[2].id,ans[1][2] = ans[2][2] = ans[3][2] = ans[3][3] = x[3].id,ans[1][3] = ans[2][3] = x[1].id;
}
if (x[3].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[3].id,ans[1][2] = ans[2][2] = ans[3][2] = x[2].id,ans[1][3] = ans[2][3] = ans[3][3] = x[1].id;
}
}
if (m == 4){
if (x[4].val == 6){
ans[1][1] = ans[1][2] = ans[1][3] = ans[2][1] = ans[2][2] = ans[3][1] = x[4].id,ans[2][3] = x[3].id,ans[3][2] = x[2].id,ans[3][3] = x[1].id;
}
if (x[4].val == 5){
ans[1][1] = ans[1][2] = ans[2][1] = ans[2][2] = ans[3][1] = x[4].id,ans[2][3] = ans[3][2] = x[3].id,ans[1][3] = x[2].id,ans[3][3] = x[1].id;
}
if (x[4].val == 4&&x[3].val == 3){
ans[1][1] = ans[2][1] = ans[2][2] = ans[3][1] = x[4].id,ans[1][2] = ans[2][3] = ans[3][2] = x[3].id,ans[1][3] = x[2].id,ans[3][3] = x[1].id;
}
if (x[4].val == 4&&x[3].val == 2){
ans[1][1] = ans[2][1] = ans[2][2] = ans[3][1] = x[4].id,ans[1][2] = ans[2][3] = x[3].id,ans[3][2] = ans[3][3] = x[2].id,ans[1][3] = x[1].id;
}
if (x[4].val == 3&&x[3].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[4].id,ans[1][2] = ans[2][2] = ans[3][2] = x[3].id,ans[1][3] = ans[2][3] = x[2].id,ans[3][3] = x[1].id;
}
if (x[4].val == 3&&x[3].val == 2){
ans[1][1] = ans[1][2] = x[1].id,ans[2][1] = ans[3][1] = x[2].id,ans[2][2] = ans[3][2] = x[3].id,ans[1][3] = ans[2][3] = ans[3][3] = x[4].id;
}
}
if (m == 5){
if (x[5].val == 5){
ans[1][1] = ans[1][2] = ans[2][1] = ans[2][2] = ans[3][1] = x[5].id;
int res = m;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
if (x[5].val == 4){
ans[1][1] = ans[2][1] = ans[2][2] = ans[3][1] = x[5].id,ans[1][2] = ans[2][3] = x[4].id;
int res = m-1;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
if (x[5].val == 3&&x[4].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[5].id,ans[1][2] = ans[2][2] = ans[3][2] = x[4].id;
int res = m-1;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
if (x[5].val == 3&&x[4].val == 2){
ans[1][1] = ans[2][1] = ans[3][1] = x[5].id,ans[1][2] = ans[2][2] = x[4].id,ans[2][3] = ans[3][2] = x[3].id,ans[1][3] = x[2].id,ans[3][3] = x[1].id;
}
}
if (m == 6){
if (x[6].val == 4){
ans[1][1] = ans[2][1] = ans[2][2] = ans[3][1] = x[6].id;
int res = m;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
if (x[6].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[6].id,ans[2][2] = ans[3][2] = x[5].id;
int res = m-1;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
}
if (m == 7){
if (x[7].val == 3){
ans[1][1] = ans[2][1] = ans[3][1] = x[7].id;
int res = m;
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++){
if (!ans[i][j]) ans[i][j] = x[--res].id;
}
}
}
}
}
printf("yes\n");
for (int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++) printf("%d ",ans[i][j]);
puts("");
}
}
int b[maxn];
void subtask4(){
int sum = 0,num = 0;
for (register int i = 1;i <= m;i++){
if (x[i].val == 2) b[++sum] = x[i].id;
}
for (register int i = 1;i <= m;i++){
if (x[i].val > 2) num += x[i].val-3;
}
if (sum < num) {printf("no\n");return;}
int cnt = 0;
for (register int i = m;i >= 1;i--){
if (x[i].val > 2){
ans[1][++cnt] = x[i].id;
ans[2][cnt] = x[i].id;
ans[3][cnt] = x[i].id;
for (int j = 1;j <= x[i].val-3;j++){
ans[3][++cnt] = x[i].id;
ans[1][cnt] = b[sum],ans[2][cnt] = b[sum--];
}
}
}
int cnt1 = cnt,cnt2 = cnt,cnt3 = cnt;
for (register int i = sum;i >= 1;i--){
if (x[i].val == 2&&cnt1 < n) ans[1][++cnt1] = x[i].id,ans[2][++cnt2] = x[i].id;
else if (x[i].val == 2) ans[3][++cnt3] = x[i].id,ans[3][++cnt3] = x[i].id;
else {
if (cnt1 < n) {ans[1][++cnt1] = x[i].id;continue;}
if (cnt2 < n) {ans[2][++cnt2] = x[i].id;continue;}
if (cnt3 < n) {ans[3][++cnt3] = x[i].id;continue;}
}
}
printf("yes\n");
for (register int i = 1;i <= 3;i++){
for (int j = 1;j <= n;j++) printf("%d ",ans[i][j]);
puts("");
}
}
int main(){
freopen("circuit.in","r",stdin);
freopen("circuit.out","w",stdout);
n = read(),m = read();
for (int i = 1;i <= m;i++) x[i].val = read(),x[i].id = i;
sort(x+1,x+m+1,cmp);
if (m == 1) {subtask1();return 0;}
if (x[m].val <= 2) {subtask2();return 0;}
if (n <= 3&&m <= 9) {subtask3();return 0;}
if (x[1].val >= 2){subtask4();return 0;}
return 0;
}
/*
10 11
3 3 2 3 4 2 3 3 5 2 2
*/