Codeforces 1332C. K-Complete Word(思维)

题目链接:https://codeforces.ml/problemset/problem/1332/C

题意:给你一个字符串 s s s,问你把他变成一个周期为 k k k的周期回文字符串最少需要改变多少个字符。

思路:一看到这种题目,我第一想法就是 d p dp dp,然后,我就放弃啦。 Q A Q QAQ QAQ
看过题解才知道,原来就是一个暴力。哭唧唧
因为这是一个周期回文字符串,那么每一个周期一定是一个回文串。所以改变之后满足条件的自负床一定满足 s [ i ] = s [ k − i + 1 ] , s [ i + k ] = s [ k + k − i + 1 ] . . . s[i] = s[k-i+1],s[i+k] = s[k+k-i+1] ... s[i]=s[ki+1],s[i+k]=s[k+ki+1]...
那我们不就直接开个二维数组把每一位出现的所有字符出现的个数记录下来,找出最多的一个记为 c n t cnt cnt,答案加上 2 × n k − c n t 2 \times \frac{n}{k} - cnt 2×kncnt,但要注意 k k k为奇数时为 n k − c n t \frac{n}{k} - cnt kncnt
最后, c f cf cf为什么总是卡 m e m s e t memset memset呀? Q A Q QAQ QAQ

AC代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define LL long long
#define pii pair
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i++)
#define per(i,a,b) for(int i = (a) ; i >= (b) ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)

const int INF = 1e9 + 10;
const LL mod = 2019;
const int maxn = 2e5 + 7;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while (c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + (c - '0');
        c = getchar();
    }
    return x * f;
}

int head[maxn << 1];
struct Edge {
    int to, next;
}edge[maxn << 1];
int tot;

void init() {
    memset(head, -1, sizeof(head));
    tot = 0;
}

void addedge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

LL qpow(LL a, LL b, LL p) {
    LL res = 1;
    while (b) {
        if (b & 1) res = (res * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return res;
}

char s[maxn];
int vis[maxn][30];

int main() {
    int T;
    sd(T);
    while(T--) {
        int n,k;
        sd(n),sd(k);
        scanf("%s",s+1);
        rep(i,0,k) {
            rep(j,0,25) {
                vis[i][j] = 0;
            }
        }
        for(int i = 1 , j = k ; i <= j ; i++ , j--) {
            for(int l = 0 ; i + l * k <= n ; l++) {
//                cout << "(" << i + l * k << " " << j + l * k << ") ";
                if(i != j) {
                    vis[i][s[i+l*k]-'a']++;
                    vis[i][s[j+l*k]-'a']++;
                } else {
                    vis[i][s[j+l*k]-'a']++;
                }
            }
//            cout << vis[1][0] << " " << vis[1][1];
//            cout << endl;
        }
        int sum = 0;
        rep(i,1,k/2) {
            int cnt = 0;
            rep(j,0,26) {
//                cout << vis[i][j] << " o
                cnt = max(cnt,vis[i][j]);
            }
//            cout << endl;
            sum += 2 * (n / k) - cnt;
//            cout << "i = " << i << " cnt = " << cnt << endl;
        }
        if(k&1) {
            int cnt = 0;
            rep(i,0,26) {
                cnt = max(cnt,vis[k/2+1][i]);
            }
            sum += n / k - cnt;
        }
        pd(sum);
    }
    return 0;
}

你可能感兴趣的:(暴力)