Codeforces Round #528 (Div. 1, based on Technocup 2019 Elimination Round 4) C. Vasya and Templates

本文详细解析了Codeforces比赛中的C题,通过分析题目的要求和限制,提供了有效的解题策略,并附上了完整的代码实现。文章强调了使用临时数组的重要性,避免在检查过程中出现错误或清除不干净的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
http://codeforces.com/contest/1086/problem/C

 

题解:
https://blog.youkuaiyun.com/Dream_Lolita/article/details/85239751

或者:

http://codeforces.com/blog/entry/64078

 

这里要注意的是,不能只用used[ ]和cg[ ],然后再想着如果不行就清零,而是一定要用临时数组use[ ]和tg[ ],第一这样不容易出错,第二,由于这里的check_up和check_down函数中cg[ ]的赋值不是顺序的(从1-->i这样的),而是类似哈希的赋值,所以最终如果某种方式失败后返回前清零,不一定能清除干净!!!!!

 

代码:

#include<stdio.h>
#include<string.h>
using namespace std;
const int N=1e6+10,M=28;
int n,flag,ff,cnt;
int a[N],b[N],c[N];
int tg[M],cg[M],bo[M];
bool used[M],use[M];
char A[N],B[N],C[N];

void Clear()
{
	flag=1;cnt=0;
	memset(used,0,sizeof(used));memset(use,0,sizeof(use));memset(tg,0,sizeof(tg));
	memset(bo,0,sizeof(bo));memset(cg,0,sizeof(cg));
}

void output()
{
	int i,j;
	for(i=1;i<=cnt;i++)
    {
        if(!cg[i]&&tg[i])
            cg[i]=tg[i];
        if(!used[i]&&use[i])
            used[i]=1;
    }
	for(i=1;i<=cnt;i++)
    {
        if(!cg[i])
        {
            for(j=1;j<=cnt;j++)
            {
                if(!used[j])
                {
                    used[j]=1;
                    cg[i]=j;
                    break;
                }
            }
            if(!cg[i])
            {
                puts("NO");
                return;
            }
        }
    }
    puts("YES");
    for(i=1;i<=cnt;i++)
        printf("%c",cg[i]-1+'a');
    printf("\n");
    return;
}

void checkup(int p)
{
	for(int i=p+1;i<n;++i)
	{
		if(tg[c[i]])
		{
			if(tg[c[i]]>a[i]) return;
			if(tg[c[i]]==a[i]) continue;
			ff=0;break;
		}
		else
		{
			for(int j=a[i]+1;j<=cnt;++j)
				if(!use[j]) {tg[c[i]]=j;use[j]=1;return;}
			if(!use[a[i]]) {tg[c[i]]=a[i];use[a[i]]=1;continue;}
			ff=0;break;
		}
	}
}

void checkdown(int p)
{
	for(int i=p+1;i<n;++i)
	{
		if(tg[c[i]])
		{
			if(tg[c[i]]<b[i]) return;
			if(tg[c[i]]==b[i]) continue;
			ff=0;break;
		}
		else
		{
			for(int j=1;j<b[i];++j)
				if(!use[j]) {tg[c[i]]=j;use[j]=1;return;}
			if(!use[b[i]]) {tg[c[i]]=b[i];use[b[i]]=1;continue;}
			ff=0;break;
		}
	}
}

int main()
{
    int T;
	scanf("%d",&T);
	while(T--)
	{
		Clear();
		scanf("%d",&cnt);
		scanf("%s%s%s",C,A,B);n=strlen(C);
		if(strcmp(A,B)>0) {puts("NO");continue;}
		for(int i=0;i<n;++i)
		{
			a[i]=A[i]-'a'+1,b[i]=B[i]-'a'+1,c[i]=C[i]-'a'+1;
		}
		int i;
		for(i=0;i<n;++i)
		{
			if(a[i]!=b[i]) break;
			if(cg[c[i]])
			{
				if(cg[c[i]]==a[i]) continue;
				else {flag=0;break;}
			}
			else
			{
				if(used[a[i]]){flag=0;break;}
				cg[c[i]]=a[i],used[a[i]]=1;
			}
		}
		if(i>=n){output();continue;}
		if(!flag) {puts("NO");continue;}
		if(cg[c[i]])
		{
			if(cg[c[i]]>a[i] && cg[c[i]]<b[i]) {output();continue;}
			if(cg[c[i]]<a[i] || cg[c[i]]>b[i]) {puts("NO");continue;}
			ff=1;memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
			if(cg[c[i]]==a[i]) checkup(i);
			else checkdown(i);
			if(ff) {output();continue;}
		}
		else
		{
			for(int j=a[i]+1;j<b[i];++j) if(!used[j]) {cg[c[i]]=j;used[j]=1;break;}
			if(cg[c[i]]>a[i] && cg[c[i]]<b[i]) {output();continue;}
			if(!used[a[i]])
			{
				memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
				ff=1;tg[c[i]]=a[i];use[a[i]]=1;
				checkup(i);
				if(ff) {output();continue;}
			}
			if(!used[b[i]])
			{
				memcpy(tg,cg,sizeof(cg));memcpy(use,used,sizeof(used));
				ff=1;tg[c[i]]=b[i];use[b[i]]=1;
				checkdown(i);
				if(ff) {output();continue;}
			}
		}
		puts("NO");
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值