【洛谷P2580】于是他错误的点名开始了【Trie】

本文介绍了一种使用Trie树和map解决字符串匹配问题的方法。针对一组预定义的字符串集合,当遇到新的字符串时,能够判断该字符串是否曾出现过、是否为首次出现,还是完全未出现。提供两种实现方式:一种基于Trie树,另一种则利用STL map。

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P2580
先给出 n n n个字符串,之后再给出 m m m个串 s s s,若 s [ i ] s[i] s[i]在那 n n n个字符串中出现过且在 m m m串中第一次出现,输出"OK",如果出现在 n n n串单在 m m m串中出现过,输出"REPEAT",如果没有出现在 n n n串输出 W R O N G WRONG WRONG


思路:

这道题正解是 T r i e Trie Trie,当然如果你想用 S T L STL STL m a p map map做也没有人拦你。
首先将前 n n n个串插入到 T r i e Trie Trie里,之后读入的 m m m个串就在字典树里查找,如果找到并且是第一次出现,那么就返回"OK",否则返回"REPEAT",如果根本找不到或就返回"WRONG"。
m a p map map的话就将前 n n n个串放进数组,然后每读入一个串就在数组里查找。跟字典树思路是基本一样的。


代码:

T r i e Trie Trie
#include <cstdio>
#include <string>
#include <iostream>
#define N 300000
using namespace std;

int n,trie[N+1][31],num;
string read;
bool end[N+1],sum[N+1];

void Insert(string s)  //插入
{
	int p=1;
	for (int i=0;i<s.size();i++)
	{
		if (!trie[p][s[i]-'a'+1])  //没有这个点
		 trie[p][s[i]-'a'+1]=++num;  //新建节点
		p=trie[p][s[i]-'a'+1];  //继续搜
	}
	end[p]=true;  //记录
	return;
}

string find (string s)  //查找
{
	int p=1;
	for (int i=0;i<s.size();i++)
	 if (!(p=trie[p][s[i]-'a'+1])) return "WRONG";  //找不到这个串
	if (!end[p]) return "WRONG";  //找到但是没有在这里结束就退出
	  //就像n串有一个abcde,m串有一个abc,你能在Trie里找到abc,但是实际上是abcde的一部分,不算找到。
	if (!sum[p])  //找到且为第一次
	{
		sum[p]=true;
		return "OK";
	}
	return "REPEAT";  //多次,之前找到过
}

int main()
{
	scanf("%d\n",&n);
	for (int i=1;i<=n;i++)
	{
		cin>>read;
		Insert(read);
	}
	scanf("%d\n",&n);
	for (int i=1;i<=n;i++)
	{
		cin>>read;
		cout<<find(read)<<endl;
	}
	return 0;
}
m a p map map
#include <cstdio>
#include <string>
#include <map>
#include <iostream>
using namespace std;

string s;
int n;
map<string,int> a;  //map

int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        cin>>s;
        a[s]=1;  //记录,类似hash
    }
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        cin>>s;
        if (a[s]==1)
        {
            puts("OK");
            a[s]=2;
        }
        else if (a[s]==2)
        {
            puts("REPEAT");
        }
        else puts("WRONG");
    }
    return 0;
}
关于 阿里云盘CLI。仿 Linux shell 文件处理命令的阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能,支持相册批量下载。 特色 多平台支持, 支持 Windows, macOS, linux(x86/x64/arm), android, iOS 等 阿里云盘多用户支持 支持备份盘,资源库无缝切换 下载网盘内文件, 支持多个文件或目录下载, 支持断点续传和单文件并行下载。支持软链接(符号链接)文件。 上传本地文件, 支持多个文件或目录上传,支持排除指定文件夹/文件(正则表达式)功能。支持软链接(符号链接)文件。 同步备份功能支持备份本地文件到云盘,备份云盘文件到本地,双向同步备份保持本地文件和网盘文件同步。常用于嵌入式或者NAS等设备,支持docker镜像部署。 命令和文件路径输入支持Tab键自动补全,路径支持通配符匹配模式 支持JavaScript插件,你可以按照自己的需要定制上传/下载中关键步骤的行为,最大程度满足自己的个性化需求 支持共享相册的相关操作,支持批量下载相册所有普通照片、实况照片文件到本地 支持多用户联合下载功能,对下载速度有极致追求的用户可以尝试使用该选项。详情请查看文档多用户联合下载 如果大家有打算开通阿里云盘VIP会员,可以使用阿里云盘APP扫描下面的优惠推荐码进行开通。 注意:您需要开通【三方应用权益包】,这样使用本程序下载才能加速,否则下载无法提速。 Windows不第二步打开aliyunpan命令行程序,任何云盘命令都有类似如下日志输出 如何登出和下线客户端 阿里云盘单账户最多只允许同时登录 10 台设备 当出现这个提示:你账号已超出最大登录设备数量,请先下线一台设备,然后重启本应用,才可以继续使用 说明你的账号登录客户端已经超过数量,你需要先登出其他客户端才能继续使用,如下所示
### 关于洛谷 P2437 的解析与代码实现 对于洛谷上的题目 **P2437**,目前并没有直接提及该题目的具体描述或其解决方案的相关引用。然而,可以通过分析常见的算法设计思路以及可能涉及的数据结构来推测解法。 #### 解析部分 假设此题目属于典型的编程竞赛类问题,则可以考虑以下几个方向: - 若问题是关于图论的最短路径计算,可采用 Dijkstra 或 Floyd-Warshall 算法解决[^1]。 - 对于动态规划类型的题目,需定义状态转移方程并初始化边界条件[^2]。 - 如果涉及到字符串匹配或者处理,KMP 或者 Trie 树可能是有效的工具之一[^3]。 以下是基于上述几种可能性给出的一个简单例子——使用 Python 实现的单源最短路径 (SSSP) 问题求解: ```python import heapq def dijkstra(graph, start_node): distances = {node: float('inf') for node in graph} distances[start_node] = 0 priority_queue = [(0, start_node)] while priority_queue: current_distance, current_node = heapq.heappop(priority_queue) if current_distance > distances[current_node]: continue for neighbor, weight in graph[current_node].items(): distance = current_distance + weight if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(priority_queue, (distance, neighbor)) return distances ``` 以上代码片段展示了如何利用优先队列优化后的 Dijkstra 算法寻找加权有向图中的最小距离集合[^4]。 #### 可能存在的资源链接 由于未找到确切针对洛谷 P2437 的讨论文章或项目页面,建议尝试通过搜索引擎进一步查询关键词组合如下所示: - `"洛谷 P2437" site:github.com` - `"洛谷 P2437 题解" site:cnblogs.com` 这有助于定位更具体的资料来源。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值