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
*/
posted @ 2021-07-16 19:17  小又又yyyy  阅读(43)  评论(0编辑  收藏  举报