zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    		for (int i = 1;i <= ans;i++) printf("%d %d %d
    ",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
    ",ans);
    			for (int i = 1;i <= ans;i++) printf("%d %d %d
    ",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
    ",ans);
    	for (int i = 1;i <= ans;i++) printf("%d %d %d
    ",step[i][0],step[i][1],step[i][2]);
    	return 0;
    }
    /*
    00000000000000000000000000001010000
    10101010101001111010101000101010101
    */
    

    T2

    分块题,不怎么会,明天补

    T3

    首先对于m = 1和(x_i leq 2)有很显然的构造方式

    然后我把目光看向了(nleq 3,mleq 9),暴力打了个表……,真的是纯在打表

    最后看(x_igeq 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
    1
    1
    1
    ");
    	else printf("no
    ");
    }
    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
    ");
    	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
    ");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
    ");
    	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
    ");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
    ");
    	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
    */
    
  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/little-uu/p/15021572.html
Copyright © 2011-2022 走看看