D. Min Cost String

链接

https://codeforces.com/problemset/problem/1511/D

题目

思路

显然原题的意思就是长度为2的子串出现次数取C(2,x),那么我们只要保证每个字串出现的最平均就行。如果有k个字母,那么最多不同的子串有k*k个。所以我们就直接找到一个最小的母串,然后重复遍历就行。这里如何构建母串呢?可以采用dp[x][y]表示有没有出现,然后利用双指针:i指向当前位置,j指向下一个的位置,初始时j等于i,然后循环遍历找到第一个没出现的子串。并添加计数器,当出现k*k-1个子串的时候就退出循环,直接开始复制就行。因为剩下那个正好首尾相接!!!这个点被卡了好久。

代码

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
#define int long long


bool dp[27][27];
signed main()
{
	IOS;
	int n, k;
	cin >> n >> k;
	string s;
	s += '1';
	int already = 0;
	string sx;

	for (int i = 1; i < n; i++)
	{
		if (already == k*k - 1)//计数器
		{
			break;
		}
		int j = s[i - 1] - '0';
		while (dp[s[i - 1] - '0'][j]) { j = (j + 1) % k; if (!j)j = k; }//循环遍历
		already++;
		dp[s[i - 1] - '0'][j] = 1;//标记
		char x = j + '0';
		s += x;
	}
	for (int i = 0; i < n; i++)
	{
		int x = s[i % s.length()] - '0';
		char xx = x + 'a' - 1;
		cout << xx;
	}
	return 0;
}

posted on 2024-07-19 11:25  WHUStar  阅读(1)  评论(0编辑  收藏  举报