[codeforces 1354B] Ternary String 寻找6种组合

Educational Codeforces Round 87 (Rated for Div. 2)  参与排名人数11499,比赛前遇到2次延时,17:05-17:15,17:15-17:20

[codeforces 1354B]   Ternary String   寻找6种组合

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址http://codeforces.com/contest/1354/problem/B

Problem Lang Verdict Time Memory
B - Ternary String GNU C++17 Accepted 31 ms 8500 KB

没想到AtCoder的D题难度,CodeForces曾经的E题,D题难度出现在B题,一下有些接受不了。

调整了一下,进行编码,虽说思路是现成的,但编码加调试,也花了不少时间。

思路如下:

共有6种组合(213,312,123,321,132,231)

对字符的数组进行遍历,

会遇到三种字符1,2,3

若遇到颜色1,会遇到两种组合,213,312,注意,让遇到的这个位置的字符1,充当中间位置的字符。

如213,可找到离该位置最近的左侧字符2的位置,可找到离该位置最近的右侧字符3的位置,

根据字符3与字符2间距,找最小值。

若遇到字符2,思路如上。

若遇到字符3,思路如上。

若觉得文字理解不了,请看如下模拟

112233

4

位置1    2    3    4    5    6  
数值1    1    2    2    3    3
读到位置1(对应字符1):左边找不到其它字符,此组数据无效

读到位置2(对应字符1):左边找不到其它字符,此组数据无效

读到位置3(对应字符2):
左边找到最近的字符1(位置2),右边找到最近的字符3(位置5),该组组合123,对应位置(2,3,5)
值5-2+1=4

读到位置4(对应字符2):
左边找到最近的字符1(位置2),右边找到最近的字符3(位置5),该组组合123,对应位置(2,4,5)
值5-2+1=4

读到位置5(对应字符3):
右边找不到其它字符,此组数据无效

读到位置6(对应字符3):
右边找不到其它字符,此组数据无效

在上述值中,取最小值4

AC代码如下

#include 
#include 
#include 
#define maxn 200010
using namespace std;
char s[maxn];
int a1[maxn],b1[maxn],c1[maxn],a2[maxn],b2[maxn],c2[maxn],mn;
int main(){
	int t,n,i;
	scanf("%d",&t);
	while(t--){
		scanf("%s",s+1);
		n=strlen(s+1),mn=maxn;
		for(i=0;i<=n;i++)a1[i]=b1[i]=c1[i]=0;//初始化
		for(i=1;i<=n+1;i++)a2[i]=b2[i]=c2[i]=n+1;//初始化
		for(i=1;i<=n;i++)
			if(s[i]=='1')a1[i]=i,b1[i]=b1[i-1],c1[i]=c1[i-1];//a1[i]记录左边离i位置最近的字符1的位置(包括了i位置)
			else if(s[i]=='2')b1[i]=i,a1[i]=a1[i-1],c1[i]=c1[i-1];//b1[i]记录左边离i位置最近的字符2的位置(包括了i位置)
			else if(s[i]=='3')c1[i]=i,a1[i]=a1[i-1],b1[i]=b1[i-1];//c1[i]记录左边离i位置最近的字符3的位置(包括了i位置)
		for(i=n;i>=1;i--)
			if(s[i]=='1')a2[i]=i,b2[i]=b2[i+1],c2[i]=c2[i+1];//a2[i]记录右边离i位置最近的字符1的位置(包括了i位置)
			else if(s[i]=='2')b2[i]=i,a2[i]=a2[i+1],c2[i]=c2[i+1];//b2[i]记录右边离i位置最近的字符2的位置(包括了i位置)
			else if(s[i]=='3')c2[i]=i,a2[i]=a2[i+1],b2[i]=b2[i+1];//c2[i]记录右边离i位置最近的字符3的位置(包括了i位置)
		if(!a1[n]||!b1[n]||!c1[n]){printf("0\n");continue;}//1,2,3字符有缺失
		for(i=1;i<=n;i++){//i代表所要寻找的中间位置
			if(s[i]=='1'){
				if(b1[i]>0&&c2[i]0&&b2[i]0&&c2[i]0&&a2[i]0&&b2[i]0&&a2[i]

类似题目:

[codeforces 1337D] Xenia and Colorful Gems 寻找6种组合

AtCoder Beginner Contest 162 D RGB Triplets 前缀和

[codeforces 1335E1] Three Blocks Palindrome (easy version) 分成左中右3个区间+前缀和

[codeforces 1335E2] Three Blocks Palindrome (hard version) 从中间位置向两边扩散

 

你可能感兴趣的:(codeforces)