构造字符串 之 hdu 4850 Wow! Such String!

/*
话说之前读题都没读懂。。。
Each substring of A with length equal to or larger than 4 can appear in the string exactly once.
A的每个长度大于等于4的子串出现在传中恰好一次。(即:大于等于4的子串不能重复出现)
 
跟大神学的一种方法。。。
首先,长度为4的字符串有26^4种,故可猜测满足题意的最大长度的字符串的长度是26^4+3 (+3是因为鸽巢原理)。
 
此题关键就在于如何构造满足题意的字符串(废话啊。。。)
用数组used[][][][],来判断长度为4的字符串是否出现重复。
即:在每次增加一个字符(位置为pos),选择字母是时,判断used[str[pos-3]][str[pos-2]][str[pos-1]][str[pos]],是否为true,
若真,说明此子串之前有用过,无法选择该字母,
否则,可选。
复杂度:所能构造的最长字符串*26 <= (500000*26),可AC。。。
 
注意:
要先把 aaaa,bbbb,...,zzzz放到字符串中,否则它们无法被构造出来。
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX = 500005;
int N, len;
int str[MAX];
bool used[26][26][26][26];


int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	memset(used, false, sizeof(used));
	len = 0;

	for (int i = 0; i < 26; ++i) {
		for (int j = 0; j < 4; ++j) {
			str[len++] = i;
		}
	}


	for (int i = 0; i < (len - 3); ++i) {
		used[str[i]][str[i + 1]][str[i + 2]][str[i + 3]] = true;
	}

	bool Judge = true;

	while (Judge) {
		Judge = false;
		for (int i = 0; i < 26; ++i) {
			if (!used[str[len - 3]][str[len - 2]][str[len - 1]][i]) {
				str[len] = i;
				used[str[len - 3]][str[len - 2]][str[len - 1]][i] = true;
				len++;
				Judge = true;
			}
		}
	}

	while (~scanf("%d", &N)) {
		if (N > len) {
			printf("Impossible\n");
		}
		else {
			for (int k = 0; k < N; ++k) {
				printf("%c", 'a' + str[k]);
			}
			printf("\n");
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值