51Nod1523 非回文

Problem

一个字符串是非回文的,当且仅当,他只由前p个小写字母构成,而且他不包含长度大于等于2的回文子串。

给出长度为n的非回文串s。请找出字典序比s大的,而且字典序要最小的长度为n的非回文。

Solution

非回文条件是s[i-2]!=j&&s[i-1]!=j,从前向后找。

Code

#include<stdio.h>
#include<set>
#include<iostream>
#include<stack>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod=998244353;
ll mo(ll a,ll p){
    return a>=p?a%p:a;
}
inline int rd() {
    int x = 0, f = 1;
    char ch;
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}
inline ll gcd(ll x, ll y){
    return y==0?x:gcd(y,x%y);
}
inline ll speed(ll a,ll b){
    ll cur=a,anss=1;
    while(b){
        if(b&1) anss=anss*cur;
        cur=cur*cur;
        b>>=1;
    }
    return anss;
}
const int MAXN=1e5;
bool ipr[MAXN+20];
int cnt,pri[MAXN/5];
void prime(){//埃式筛法
    int N=sqrt(MAXN)+0.5,mul;
    memset(ipr,true,sizeof(ipr));
    ipr[1]=false;
    for(int i=2;i<=N;i++){
        if(ipr[i]==true){
            i==2?mul=1:mul=2;
            for(int j=i*i;j<=MAXN;j+=i*mul){
                ipr[j]=false;
            }
        }
    }
    for(int i=2;i<=MAXN;i++){
        if(ipr[i]==true){
            pri[++cnt]=i;
        }
    }
}
int n,p;
char s[1020];
int main(){
    //io_opt;
    scanf("%d%d",&n,&p);
    scanf("%s",s);
    bool fg=false;
    int t=-1;
    for(int i=n-1;i>=0;i--){
        for(char j=s[i]+1;j<'a'+p;j++){
            if(i>=2&&s[i-2]==j) continue;
            if(i>=1&&s[i-1]==j) continue;
            fg=true;
            s[i]=j;
            t=i+1;
            break;
        }
        if(fg) break;
    }
    if(!fg){
        printf("NO
");
        return 0;
    }
    for(int i=t;i<n;i++){
        for(char j='a';j<'a'+p;j++){
            if(i>=2&&s[i-2]==j) continue;
            if(i>=1&&s[i-1]==j) continue;
            s[i]=j;break;
        }
    }
    printf("%s",s);
    return 0;
}

原文地址:https://www.cnblogs.com/sz-wcc/p/13187961.html