首页 > 其他分享 >题解 CF379D New Year Letter

题解 CF379D New Year Letter

时间:2023-08-14 22:11:20浏览次数:49  
标签:字符 AC int 题解 s1 个数 Year CF379D

思路

提供一种比较容易想到的做法。

拿到题看数据范围发现都很小,所以放心大胆地暴力。

容易发现 \(s_i\) 中 AC 的个数等于 \(s_{i-2}\) 中 AC 的个数加 \(s_{i-1}\) 中 AC 的个数再加上两者拼接处可能有的一个 AC

所以 \(s_1\) 和 \(s_2\) 从第二个字符到倒数第二个字符这之间的 AC 串的排布与后面拼接没有任何关系。枚举里面有几个 AC 即可。不是 AC 的地方用一个无关字母表示就没有贡献了(我的代码中用的是 X)。

然后对于 \(s_1\) 和 \(s_2\) 第一个和最后一个字符,仍然是大力枚举这个字符(分别为 XAC 的时候),然后直接模拟,判断最后结果是不是等于给定的 \(x\) 即可。

模拟的具体方法就是记录前两个串的第一个和最后一个字符然后判断有没有新 AC 产生即可。

Code

#include<bits/stdc++.h>
using namespace std;
int n,m,k,x;
char s1[110],s2[110],s[4]={"\0AC"};
void fun(int fir1,int las1,int fir2,int las2){
	int sum,l1,l2,q1,q2,w1,w2,qq=0,ww=0;
	memset(s1,0,sizeof(s1));
	s1[1]=s[fir1];
	s1[n]=s[las1];
	if(n<=3){
		qq=1;  //串长<=3时无法写入AC,需要特判
	}
	for(int i=fir1?2:1,sum1=0;i+1<=(las1?n-1:n)||qq;i+=2,sum1++){
		qq=0;
		if(sum1){
			s1[i]='A';
			s1[i+1]='C';
		}
		else{
			i-=2;
		}
		memset(s2,0,sizeof(s2));
		s2[1]=s[fir2];
		s2[m]=s[las2];
		if(m<=3){
			ww=1;
		}
		for(int j=fir2?2:1,sum2=0;j+1<=(las2?m-1:m)||ww;j+=2,sum2++){
			ww=0;
			if(sum2){
				s2[j]='A';
				s2[j+1]='C';
			}
			else{
				j-=2;
			}
            //模拟。
			l1=sum1;//s[i-2]的答案
			l2=sum2;//s[i-1]的答案
			q1=fir1;//s[i-2]的头
			q2=fir2;//s[i-1]的头
			w1=las1;//s[i-2]的尾
			w2=las2;//s[i-1]的尾
			if(n==1){
				q1=las1;
			}
			if(m==1){
				q2=las2;//特判覆盖了
			}
			for(int kk=3;kk<=k;kk++){
				sum=l1+l2+(w1==1&&q2==2);
				l1=l2;
				l2=sum; //模拟,更新
				swap(q1,q2);
				w1=w2;
				if(sum>x){
					break;
				}
			}
			if(sum==x){
				for(int kk=1;kk<=n;kk++){
					if(s1[kk]){
						printf("%c",s1[kk]);
					}
					else{
						printf("X");
					}
				}
				printf("\n");
				for(int kk=1;kk<=m;kk++){
					if(s2[kk]){
						printf("%c",s2[kk]);
					}
					else{
						printf("X");
					}
				}
				exit(0);
			}
		}
	}
}
int main(){
	scanf("%d%d%d%d",&k,&x,&n,&m);
	if(x==0){
		for(int i=1;i<=n;i++){
			printf("A");
		}
		printf("\n");
		for(int i=1;i<=m;i++){
			printf("A");
		}
		return 0;
	}
    //枚举头尾
	for(int i=0;i<=2;i++){
		for(int j=0;j<=2;j++){
			for(int k=0;k<=2;k++){
				for(int l=0;l<=2;l++){
					fun(i,j,k,l);
				}
			} 
		}
	}
	printf("Happy new year!");
}

完结撒花!!

标签:字符,AC,int,题解,s1,个数,Year,CF379D
From: https://www.cnblogs.com/zhicheng123/p/17629916.html

相关文章

  • P4412 题解
    P4412题解传送门更好的阅读体验简化题意:一张无向图,给定一棵生成树,求最小的修改边权的代价使得这棵生成树是最小生成树,代价定义为修改前后一条边的边权变化量的绝对值。思路首先,发现让这棵树成为最小生成树不好直接处理,但是判定是否为最小生成树却相对更容易。判定的思路......
  • CF1845D Rating System 题解
    题面给定一个长度为\(n\)数列\(a\),保证每项都不为\(0\)。初始时\(x=0\),然后对于\(1\lei\len\),按顺序进行如下操作:如果\(x\gek\),则\(x\rightarrow\max(k,x+a_i)\),否则\(x\rightarrowx+a_i\)。你需要求出\(k\),使得\(x\)的值尽量大。题解如果我们不考虑\(k......
  • Ynoi2001 冷たい部屋、一人 题解
    \(\text{link}\),这题太毒瘤啦!难写难调还略微卡常。谁爱卡常谁卡吧。反正我先贺为敬了。——引用自洛谷别人的提交记录本人写了两天(两个\(case\)各一天),调崩溃了才调出来,太毒瘤了!看到颜色相同发现不弱于\(O(n\sqrtn)\),一眼根号分治,设阈值为\(B\)。case1对于颜色出现次......
  • [ARC126C] Maximize GCD 题解
    题意给定一个序列\(A\),每次操作可以使\(A_i+1\)(\(i\in\left[1,n\right]\),\(K\)次操作的\(i\)可以不同),最多可以做\(K\)次。问\(\gcd{A_1,A_2,...,A_n}\)的最大值。题解首先,如果\(K\)可以把当前序列中所有的数都加到\(A_{\max}\),那就全部加到\(A_{\max}\),在......
  • [ABC215D] Coprime 2 题解
    题意给定数列\(A_N\)和一个正整数\(M\),求出所有的\(1\lek\leM\)满足\(\foralli\in\left[1,N\right],\gcd(k,A_i)=1\)。题解本题存在线性复杂度算法。记\(\operatorname{lpf}(n)=[1<n]\min\{p:p\midn\}+[1=n]\),即\(n\)的最小质因数。特别地,\(n......
  • [ARC126D] Pure Straight 题解
    题意给定一个有\(N\)个正整数的序列\(A=(A_1,A_2,\cdots,A_N)\),且\(A_i\in\left[1,K\right]\)。你可以对这个序列做如下操作若干次。交换两个相邻的元素,也就是选出\(i\)和\(j\)满足\(\lverti-j\rvert=1\)并交换\(A_i\)和\(A_j\)。找到最小的操作数使\(......
  • CF793F Julia the snail 题解
    题意有一个长为\(n\)的杆,上面有\(m\)条绳子,每条绳子可以让蜗牛从\(l_i\)爬到\(r_i\)(中途不能离开),保证\(r_i\)各不相同。蜗牛也可以自然下落。现在有\(q\)次询问,询问\(x\)出发,途中高度不能低于\(x\)或高于\(y\),问最高能爬到的位置。\(n,m,q\leq10^5\)。题解......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——机器学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点关......
  • 「题解注释」P3345 [ZJOI2015] 幻想乡战略游戏
    题解P3345【[ZJOI2015]幻想乡战略游戏】-Baka'sBlog-洛谷博客(luogu.org)耗时:半个下午代码注释:#include<bits/stdc++.h>typedeflonglongLL;inlineintrd(){ inta=1,b=0;charc=getchar(); while(!isdigit(c))a=c=='-'?0:1,c=getcha......
  • CF1859C 题解
    思路我们实际上发现它计算的就是\(p_i\cdoti\)的和再减去一个\(p_i\cdoti\)中的最大值。那我们可以枚举这个最大值\(p_x\cdotx\),这个值就是最后和中需要删除的数值。这里我们可以使用贪心。我们可以从\(n\sim1\)枚举除\(p_i\)的每个数字需要配的数字。当然,......