c++ 魔族密码

9 篇文章 0 订阅

问题描述

魔族现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含1个字母,至多75个字母。如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。例如下面单词组成了一个词链:
i
int
integer
但下面的单词不组成词链:
integer
intern
现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链,就是包含单词数最多的词链。将它的单词数统计出来,就得到密码了。
也就是说密码就是最长词链所包括的单词数阿……

输入格式

第一行为单词表中的单词数N(1<=N<=2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词。

输出格式

只有一行,一个整数,表示输出的密码

样例输入

5
i
int
integer
intern
internet

样例输出

4

1.trie

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int N;
struct note
{
	int len;
	int son[26];
}tree[1000000];
int ans=-999999;
char S[5000];
int tot=1;
int a;
void insert(char O[])
{
	int i,t,p=1;
	int cnt=0;
	int len=strlen(O);
	for(i=0;i<len;i++)
	{
		t=O[i]-'a';
		if(tree[p].son[t]==0)
		{
			tot++;
			tree[p].son[t]=tot;
			p=tot;
		}
		else {p=tree[p].son[t];cnt=max(tree[p].len,cnt);}
	}
	tree[p].len=cnt+1;
	//cout<<tree[p].len<<endl;
	ans=max(ans,cnt+1);
}
int main()
{
	int b,c,d,e;
	scanf("%d",&N);
	for(a=1;a<=N;a++)
	{
		scanf("%s",&S);
	    insert(S);
	}
	cout<<ans;
	return 0;
	
}

 

2.dp

那么我们的dp怎么写呢?作为一只初学dp的蒟蒻,老师告诉我需要考虑四点问题:

  1. 状态:f_ifi​ 表示以第ii号位置结尾最多可以取的单词数

  2. 答案:f_nfn​

  3. 转移:f_i = max(f_j+1,f_i)fi​=max(fj​+1,fi​)

  4. 初值:f_i = 1fi​=1

那接下来的事情就很简单了,按照上述思路写代码就好啦,AC代码奉上:

#include<bits/stdc++.h>
using namespace std;
int n, f[2010], ans;
string s[2010];
int main()
{
	scanf ("%d", &n);
	for (int i=1; i<=n; i++)
		cin >>s[i];
	
	for (int i=1; i<=n; i++)
	{
		f[i] = 1;
		for (int j=1; j<i; j++)
			if (s[j]==s[i].substr(0,s[j].size())) //从s[i]的0号位置截取s[j]长度的子串,判断是否与s[j]相等。
				f[i] = max(f[j]+1, f[i]);
		ans = max(f[i], ans);
	}
	printf ("%d", ans);
	return 0;
}

 

3.STL

map<>

#include<iostream>
#include<map>
using namespace std;
map<string,int> f;
int n,ans;
string s[2005];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s[i];
        f[s[i]]++;
    }
    for(int i=1;i<=n;i++){
        int sum=0;
		string a;
        int d=s[i].size();
        for(int j=0;j<d;j++){
			a+=s[i][j],sum+=f[a];
		}
        ans=max(ans,sum);
    }
    cout<<ans;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++是一种通用的高级编程语言,它支持面向对象编程和泛型编程。C++由Bjarne Stroustrup于1983年开发,是C语言的扩展版本。C++具有强大的功能和广泛的应用领域,包括系统开发、游戏开发、嵌入式系统、图形界面等。 凯撒密码是一种简单的替换密码,它通过将字母按照一定的偏移量进行替换来加密消息。例如,偏移量为3时,字母A会被替换为D,字母B会被替换为E,以此类推。解密过程则是将每个字母按照相反的偏移量进行替换。 在C++中实现凯撒密码可以使用字符数组和循环来完成。首先,将明文消息存储在字符数组中,然后通过循环遍历数组中的每个字符,并根据偏移量进行替换。最后,将加密后的消息输出。 以下是一个简单的C++代码示例,实现了凯撒密码的加密和解密功能: ```cpp #include <iostream> using namespace std; void encrypt(string& message, int offset) { for (int i = 0; i < message.length(); i++) { if (isalpha(message[i])) { if (isupper(message[i])) { message[i] = ((message[i] - 'A' + offset) % 26) + 'A'; } else { message[i] = ((message[i] - 'a' + offset) % 26) + 'a'; } } } } void decrypt(string& message, int offset) { encrypt(message, 26 - offset); } int main() { string message = "Hello, World!"; int offset = 3; cout << "Original message: " << message << endl; encrypt(message, offset); cout << "Encrypted message: " << message << endl; decrypt(message, offset); cout << "Decrypted message: " << message << endl; return 0; } ``` 这段代码中,encrypt函数用于加密消息,decrypt函数用于解密消息。在main函数中,我们定义了一个明文消息和偏移量,然后调用encrypt函数进行加密,再调用decrypt函数进行解密。最后,输出加密和解密后的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值