POJ3080 Blue Jeans(kmp & 暴力)

11 篇文章 0 订阅
9 篇文章 0 订阅

题目链接:点击打开链接


给你m个字符串,问你最长公共子序列是什么,若长度小于3输出给定字符串,若存在多个最长公共子序列,输出字典序最小的。


kmp:从开头到结尾遍历字符串,每一个新的字符串开头都进行一次kmp,得到长度后跟原先得出的比较,长度长则直接更新,长度相

等则比较字典序。

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 65;
int m, ma, len, nxt[MAXN];
char s[MAXN][MAXN], x[MAXN], res[MAXN];
void get_nxt()
{
	nxt[0] = -1;
	int i = 0, j = -1;
	while(i < len) {
		if(j == -1 || x[i] == x[j]) nxt[++i] = ++j;
		else j = nxt[j];
	}
}
void kmp()
{
	get_nxt();
	ma = MAXN;
	for(int k = 1; k < m; ++k) {
		int i = 0, j = 0, l = 0;
		while(i < 60 && j < len) {
			if(j == -1 || s[k][i] == x[j]) {
				i++;
				j++;
			}
			else j = nxt[j];
			if(j > l) l = j;
		}
		if(l < ma) ma = l;
	}
}
int main(int argc, char const *argv[])
{
	int t;
	scanf("%d", &t);
	while(t--) {
		memset(nxt, 0, sizeof(nxt));
		scanf("%d", &m);
		for(int i = 0; i < m; ++i)
			scanf("%s", s[i]);
		int ans = 0;
		for(int i = 0; i <= 57; ++i) {
			strcpy(x, s[0] + i);
			len = 60 - i;
			kmp();
			if(ans < ma) {
				ans = ma;
				strncpy(res, s[0] + i, ans);
				res[ans] = '\0';
			}
			else if(ans == ma) {
				char tmp[MAXN];
				strncpy(tmp, s[0] + i, ans);
				tmp[ans] = '\0';
				if(strcmp(tmp, res) < 0) strcpy(res, tmp);
			}
		}
		if(ans >= 3) printf("%s\n", res);
		else printf("no significant commonalities\n");
	}
	return 0;
}


暴力:和运用kmp原理相同,strstr()函数返回前一个字符串中后一个字符串出现的首次位置,未出现则返回NULL。

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 65;
int m, len;
char s[MAXN][MAXN], x[MAXN], res[MAXN];
int main(int argc, char const *argv[])
{
	int t;
	scanf("%d", &t);
	while(t--) {
		memset(res, '\0', sizeof(res));
		scanf("%d", &m);
		for(int i = 1; i <= m; ++i)
			scanf("%s", s[i]);
		for(int i = 1; i <= 60; ++i) {
			bool flag1 = false;
			for(int j = 0; j <= 60 - i; ++j) {
				len = 0;
				bool flag2 = true;
				for(int k = j; ; ++k) {
					x[len++] = s[1][k];
					if(len == i) break;
				}
				x[len] = '\0';
				for(int k = 2; k <= m; ++k)
					if(!strstr(s[k], x)) {
						flag2 = false;
						break;
					}
				if(flag2) {
					flag1 = true;
					if(strlen(res) < strlen(x)) strcpy(res, x);
					else if(strcmp(res, x) > 0) strcpy(res, x);
				}
			}
			if(!flag1) break;
		}
		if(strlen(res) >= 3) printf("%s\n", res);
		else printf("no significant commonalities\n");
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值