[构造]CF54D

Writing a Song

题面翻译

题目大意

求一个字符串s,满足该串长度为n,只出现字母表中前k个字母,并且在指定位置必须出现指定字符串p

输入格式

第一行 n,k。(n为所需字符串的长度 n<=100,k为相应的字母大小 2<=k<=26)

第二行 p。(一个长度小于n,只包含字母表中前k个字母的字符串)

第三行 01串。(在第i个位置的数字1表示p的出现应该从s的第i个位置开始,而0表示从这里开始没有出现。)

输出格式

输出任意一个符合题意的字符串s

若无,输出“No solution”

题目描述

One of the Hedgehog and his friend’s favorite entertainments is to
take some sentence or a song and replace half of the words (sometimes
even all of them) with each other’s names.

The friend’s birthday is approaching and the Hedgehog decided to make
a special present to his friend: a very long song, where his name will
be repeated many times. But try as he might, he can’t write a decent
song!

The problem is that the Hedgehog has already decided how long the
resulting sentence should be (i.e. how many letters it should contain)
and in which positions in the sentence the friend’s name should occur,
and it must not occur in any other position in the sentence. Besides,
the Hedgehog decided to limit himself to using only the first $ K $
letters of an English alphabet in this sentence (so it will be not
even a sentence, but one long word).

The resulting problem is indeed quite complicated, that’s why the
Hedgehog asks you to help him and write a program that will make the
desired word by the given name $ P $ , the length $ N $ of the
required word, the given positions of the occurrences of the name $ P
$ in the desired word and the alphabet’s size $ K $ . Note that the
occurrences of the name can overlap with each other.

输入格式

The first line contains numbers $ N $ and $ K $ which are the length
of the required string and the alphabet size accordingly. The
limitations are: $ 1<=N<=100 $ , $ 2<=K<=26 $ .

The second line contains the name $ P $ which is a non-empty string
whose length does not exceed $ N $ characters. The string consists
only of the first $ K $ lowercase symbols of an English alphabet.

The third line contains the string of length $ N-length§+1 $ ,
consisting only of numbers zero and one. A number one in the $ i $ -th
position means that an occurrence of the name $ P $ should start from
$ i $ -th position of the desired word, while a zero means that there
is no occurrence starting here.

输出格式

Print the desired word $ S $ . If there are several answers, print any
of them.

If there is no solution, then print “No solution”.

样例 #1

样例输入 #1

5 2 aba 101

样例输出 #1

ababa

样例 #2

样例输入 #2

5 2 a 10001

样例输出 #2

abbba

样例 #3

样例输入 #3

6 2 abba 101

样例输出 #3

No solution

可怕的构造题,不会qwq,只能看题解区大佬了(大佬讲得很清楚):
https://www.luogu.com.cn/problem/solution/CF54D
构造这方面得加强qwq,贴上AC代码:

AC代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=1e6+10;
char ans[110];
int main(){
    ios::sync_with_stdio(0),cin.tie(0);
    int n,k;
    cin>>n>>k;
    string p;
    cin>>p;
    string s;
    cin>>s;
    int lenp=p.length();
    int lens=s.length();
    for(int i=0;i<lens;i++){
        if(s[i]=='1'){
            for(int j=0;j<lenp;j++){
                if(ans[i+j]&&ans[i+j]!=p[j]){
                    cout<<"No solution\n";
                    return 0;
                }
                ans[i+j]=p[j];
            }
        }
    }
    int j=0;
    for(int i=0;i<n;i++){
        if(s[i]=='0'){
            for(j=0;j<lenp;j++){
                if(ans[i+j]&&ans[i+j]!=p[j])break;
            }
            if(j==lenp){
                for(j=0;j<lenp;j++){
                    if(!ans[i+j]){
                        if(p[j]=='a')ans[i+j]='b';
                        else ans[i+j]='a';
                        break;
                    }
                }
                if(j==lenp){
                    cout<<"No solution\n";
                    return 0;
                }
            }
        }
    }
    for(int i=0;i<n;i++){
        if(!ans[i])ans[i]='a';
        cout<<ans[i];
    }
    return 0;
}

感觉还是得多想想特殊情况:
1、搜索1的时候:有没有重复占位,也就是 a n s [ i + j ] ans[i+j] ans[i+j]存在,并且 a n s [ i + j ] ! = p [ j ] ans[i+j]!=p[j] ans[i+j]!=p[j],如果存在,说明该位已经被占领了,直接 N o No No s o l u t i o n solution solution
2、搜索0的时候:看看有没有 a n s [ i + j ] ans[i+j] ans[i+j]存在,并且 a n s [ i + j ] ! = p [ j ] ans[i+j]!=p[j] ans[i+j]!=p[j],如果存在,则该位构造成功,直接 b r e a k break break,不用做重复的判断。
3、如果2的情况没有发生,我们发现这里实际上只有两种情况(与上面相对应): a n s [ i + j ] = = 0 ans[i+j]==0 ans[i+j]==0 o r or or a n s [ i + j ] = = p [ j ] ans[i+j]==p[j] ans[i+j]==p[j]。第二种情况已经没办法改变了(因为我们在上面的构造时已经确定 a n s [ i + j ] = = p [ j ] ans[i+j]==p[j] ans[i+j]==p[j]),那么我们只能改变第一种情况,看看 s [ j ] s[j] s[j]是什么,那么 a n s [ i + j ] ans[i+j] ans[i+j]构造时只需要注意不等于 s [ j ] s[j] s[j]即可(这里情况一存在的话,可以直接构造后 b r e a k break break掉,提高一点效率,后面输出时再简单构造即可)。
4、如果情况一也没有发生呢???很不幸,那就只能 N o No No s o l u t i o n solution solution了。

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值