codeforces 265 div2

本文介绍了一种高效的算法来构造指定长度的非回文字符串,并通过剪枝策略优化了搜索过程。该算法利用了回文串特性,避免了在构造过程中形成回文结构,确保最终生成的字符串符合要求。

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

div2在做的时候一直没注意到只需要判断“存不存在”回文串这一点。。。。

而判断存不存在回文串只要判断回文中心的存在,即a[i] == a[i+1] || a[i] == a[i+2]

时间复杂度为O(n)。。

于是,我们可以一边构造,一边剪枝。

但是,既然我们可以构造之后再来剪枝,就可以在构造的时候就做出限定,来提高效率。

构造出的第一个长度为n的字符串即为所求。。。

下面的代码是构造后再剪枝的。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cassert>
#include <algorithm>
#include <cmath>
#include <limits>
#include <set>
#include <map>

using namespace std;

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) a > b ? a : b
#define F(i, n) for (int (i)=0;(i)<(n);++(i))
#define REP(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define IREP(i, s, t) for(int i=s;i>=t;--i)
#define REPOK(i, s, t, o) for(int i=s;i<=t && o;++i)
#define MEM0(addr, size) memset(addr, 0, size)
#define LBIT(x) x&-x

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398

#define MAXN 1000
#define MAXM 26
#define MOD 20071027

typedef long long LL;

const double maxdouble = numeric_limits<double>::max();
const double eps = 1e-10;
const int INF = 0x7FFFFFFF;

//#define DEBUG

char buf[MAXN + 5];
char ans[MAXN + 5];
bool vis[MAXM + 5];

int n, p;
bool init = true;

bool check(int len) {
    if (init && len >= n ) {
        return false;
    }
    if (len-2 >= 0 && ans[len-1] == ans[len-2])
        return false;
    IREP(i, len-2, 1)
        if (ans[i] == ans[i-1]
            || ans[i-1] == ans[i+1])
                return false;
    return true;
}

bool dfs(int step) {
    if (step >= min(2,n)) {
        #ifdef DEBUG
        ans[step] = '\0';
        printf("out: %s\n", ans);
        #endif // DEBUG
        if (check(step)) {
            if (step >= n) {
                init = false;
                return true;
            }
        }
        else {
            init = false;
            return false;
        }

    }
    char c;
    if (init)
        c = buf[step];
    else
        c = 'a';
    REP(i, c, 'a'+p-1)
        /*if (!vis[i-'a'])*/ {
            //vis[i-'a'] = true;
            ans[step] = i;
            if(dfs(step+1))
                return true;
            //vis[i-'a'] = false;
        }
    return false;
}

int main()
{
    //freopen("input.in", "r", stdin);

    cin >> n >> p >> buf;

        if (dfs(0) == false)
            cout << "NO\n";
        else {
            ans[n] = '\n';
            cout << ans << endl;
        }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值