http://poj.org/problem?id=2503&&hash

本文介绍了三种实现英语单词翻译检索的方法:哈希表、排序加二分查找及字典树。通过具体代码示例展示了每种方法的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给你一些英语单词和这些单词翻译成其他语言时的单词,在后面给你一些其他语言的单词,看能否用字典来翻译。

思路:hash表,字典树,排序。。

我的第一个蹩脚的hash~~~~

AC代码:

#include<cstdio>
#include<string.h>
#include<iostream>
#include<string>
#define N 100005
using namespace std;
int head[N];
typedef struct str
{
	char s[11];
	char s1[11];
	int next;
}Node;
Node node[N];
void add(char *s,char *s1,int t)
{
	int m=1;
	for(int i=0;i<strlen(s);++i) m=(m*s[i])%N;
	strcpy(node[t].s,s);
	strcpy(node[t].s1,s1);
	node[t].next=head[m];
	head[m]=t;
}
char* Quary(char *s)
{
	
	int m=1;
	for(int i=0;i<strlen(s);++i) m=(m*s[i])%N;
	for(int i=head[m];i!=-1;i=node[i].next)
	if(!strcmp(s,node[i].s)) return node[i].s1;
	return "eh";
}
int main()
{
	char a[25],b[11],c[11];
	int num=0;
	memset(head,-1,sizeof(head));
	while(gets(a)&&strcmp(a,""))//""和" "不一样。。。。。
	{ 
		num++;
		int i;
		for( i=0;i<strlen(a);++i)
			if(a[i]==' ')  {a[i]='\0';break;}
			strcpy(b,a);
			strcpy(c,a+(i+1));
			add(c,b,num);
	}
	while(~scanf("%s",b))
	printf("%s\n",Quary(b));
	return 0;
}

qsort+二分

#include<iostream>
#include<string.h>
#include<cstdio>
#include<stdlib.h>
#define N 100005
using namespace std;
typedef struct str
{
	char s[11];
	char s1[11];
}Node;
Node node[N];
int cmp1(const void *a,const void *b)
{return strcmp(((Node*)a)->s,((Node*)b)->s);}
int cmp(const void *a,const void *b)
{return strcmp((char*)a,((Node*)b)->s);}
int main()
{
	char a[25];
	char b[11],c[11];
	int num=0;
	while(gets(a)&&strcmp(a,""))
	{
		int n=strlen(a),i;
		for( i=0;i<n;++i)
			if(a[i]==' ') {a[i]='\0';break;}
			strcpy(node[num].s1,a);
			strcpy(node[num++].s,a+(i+1));
	}
	qsort(node,num,sizeof(Node),cmp1);
	while(~scanf("%s",a))
	{
		Node *p=(Node*)bsearch(a,node,num,sizeof(Node),cmp);
		if(p) printf("%s\n",p->s1);
		else printf("eh\n");
	}return 0;
}

数组模拟字典树~~~~

#include<iostream>
#include<string.h>
#include<cstdio>
#include<stdlib.h>
#define N 100005
using namespace std;
typedef struct str
{
	int id;
	int next[26];
}Node;
Node node[4*N];
char ss[N][11];
int num=2;
void add(int j,char* s)
{
	int i=0,h=1;//h表示根,,,,
	while(1)
	{
		int m=s[i]-'a';
		if(node[h].next[m]==0)  node[h].next[m]=num++;
		 h=node[h].next[m];
		if(s[++i]=='\0') {node[h].id=j;return;}
	}
}
int Quary(char *s)
{
  int h=1;
  int n=strlen(s);
  for(int i=0;i<n;++i)
  {
	  int m=s[i]-'a';
	  if(node[h].next[m]==0) return -1;
	  else  h=node[h].next[m];
  }
  return node[h].id;
}
int main()
{
	char a[25],b[11];
	 int j=1;
	while(gets(a)&&strcmp(a,""))
	{ 
		int n=strlen(a),i;
		for( i=0;i<n;++i)
			if(a[i]==' '){a[i]='\0';break;}
			strcpy(ss[j],a);
			strcpy(b,a+(i+1));
			add(j++,b);
	}
	while(~scanf("%s",a))
	{
	  int k=Quary(a);
	  if(k==-1) printf("eh\n");
	  else printf("%s\n",ss[k]);
	}return 0;
}






<think>嗯,我现在要解决POJ上的3417题,题目是关于Dark roads和Network的。首先,我需要仔细理解题目内容,可能还需要翻译一下。不过用户已经要求翻译题目了,那可能他需要先了解题目大意。那我先看看原题。 题目大意是说,Y岛由许多城市和道路组成,这些道路可能连接不同的城市,也可能连接同一个城市形成环。不过,整个网络是连通的,也就是说所有城市都是可以互相到达的。最近,他们决定修建一条快速路,这条快速路属于Dark roads,也就是所谓的“暗道”。但是,由于资金问题,他们只能修建恰好一条这样的快速路。不过,这条快速路必须满足特定的条件:如果这条快速路被移除之后,剩下的网络会被分割成两个或多个不连通的部分。换句话说,这条快速路必须是当前网络中的一个桥(即,如果移除该边,图的连通性会被破坏)。 那么,现在的问题是要找出当前网络中这样的桥的数量。也就是,计算原图中有多少个边是桥。因为这些边一旦被移除,整个图就不再连通,所以这些边都是必须的,不能被任何其他路径替代。所以,每一条这样的边都可以作为候选的Dark road,也就是需要统计这样的边的数量。 不过,题目中的描述可能需要注意一些细节。例如,题目中的“暗路”只能建一条,但问题可能要求的是计算现有的桥的数量,因为每座桥都是可能的候选。例如,题目可能需要我们求出在原始网络中存在多少这样的边,使得如果在这条边上建了暗路,那么当这条暗路被移除后,网络就不再连通。所以,这实际上等同于计算图中的桥的数目。 那如何计算图中的桥的数量呢?通常,这可以通过Tarjan算法来实现。Tarjan算法可以在线性时间内找到图中的所有桥。算法的大致思想是使用深度优先搜索(DFS),并为每个节点维护发现时间和low值。low值表示该节点能回溯到的最早的节点的时间戳。如果对于某条边u→v,发现u的发现时间小于v的low值,那么这条边就是桥,因为v无法通过其他路径回到u或更早的节点。 所以,具体的步骤可能是这样的: 1. 输入数据:首先读取N和M,表示有N个城市和M条边。城市编号从0到N-1。 2. 构建图:将所有的边构建成一个无向图。 3. 应用Tarjan算法找出所有的桥。 4. 输出桥的总数。 需要注意的是,图中的边是无向的,所以在处理的时候要避免重复处理,比如每条边处理两次。在Tarjan算法中,通常会记录父节点,避免回头访问父节点而误判。 举个例子,比如测试样例中的输入: 比如样例输入: 3 3 0 1 0 2 1 2 这个图中有三个顶点,构成一个环。每条边都不是桥,所以桥的数量是0,所以输出应该是0。另一个例子可能是: 比如输入: 4 4 0 1 0 2 1 2 2 3 这个图中,边2-3是桥,其他三条边构成环。所以桥的数量是1,输出1。 那现在,我需要确保我的思路是正确的,并且能够正确应用Tarjan算法来找到桥的数量。 另外,题目中的数据规模如何呢?题目中给出的是城市数目N (N <= 10^5)吗?或者可能看原题的数据范围。原题POJ 3417的数据范围是:城市数N和边数M的范围是1 ≤ N ≤ 10^5,0 ≤ M ≤ 10^5。这个时候,使用传统的递归DFS可能会导致栈溢出问题,因为递归深度可能达到1e5层,这会导致栈空间不足,从而运行时错误。这时候,需要使用非递归的DFS实现,或者改用其他方法,比如并查集? 但Tarjan算法的时间复杂度是O(N+M),对于1e5的数据来说,应该是可以接受的。但是递归DFS可能会有问题,因为系统栈的大小可能不够。因此,可能需要用非递归的方式实现Tarjan算法。 不过,在实际编程中,特别是POJ这样的平台,可能需要考虑这一点。例如,在C++中,如果递归深度过深,会导致栈溢出。这时候,可能需要调整栈的大小,或者使用非递归的DFS。或者,可能题目中的实际数据没有这么严格,所以递归也能通过? 不过对于这个问题来说,正确的做法应该是在代码中使用Tarjan算法,并且处理大规模数据时避免栈溢出。例如,在Java中,线程的栈大小可以通过设置-Xss参数来增加,但在编程比赛中可能无法修改。因此,这种情况下可能需要用非递归的Tarjan算法。 综上,题目的解法是使用Tarjan算法找到图中的桥的数量,输出这个数目。因此,用户的问题的答案应该是,题目要求计算给定无向图中的桥的数量,而解题思路是应用Tarjan算法来找桥。</think>### 题目翻译 **题目来源**:POJ 3417 **题目名称**:暗路与网络(Dark roads) **问题描述**: Y岛由若干城市和连接它们的道路组成。道路可能连接同一对城市(形成环),但整个网络是连通的(即任意两个城市之间均可相互到达)。Y岛计划修建一条快速路作为“暗路”。暗路需满足以下条件:如果移除该暗路,剩余道路无法保持网络连通(即被分割为至少两个不连通的子网络)。 你的任务是:计算当前网络中符合暗路条件的道路数量(即原图中桥的数量)。 **输入格式**: - 输入包含多组测试数据。 - 每组数据首行为两个整数 `N` 和 `M`(1 ≤ N ≤ 10^5,0 ≤ M ≤ 10^5),分别表示城市数和道路数。 - 接下来 `M` 行,每行两个整数 `A` 和 `B`(0 ≤ A, B < N),表示城市 `A` 与 `B` 之间有一条道路。 **输出格式**: - 对于每组数据,输出符合条件的暗路数量(即桥的数量)。 ### 题目解法思路 **核心问题**:计算无向图中的桥(即删除后导致图不连通的边)。 **算法选择**:使用 **Tarjan算法** 在 O(N + M) 时间复杂度内找出所有桥。 **关键步骤**: 1. **构建图**:将输入道路存储为邻接表。 2. **Tarjan算法**: - 通过深度优先搜索(DFS)遍历图。 - 维护每个节点的发现时间 `disc[]` 和能回溯到的最早节点时间 `low[]`。 - 若边 `u→v` 满足 `disc[u] < low[v]`,则该边为桥。 3. **处理大规模数据**:递归DFS可能导致栈溢出,需改用非递归实现或确保栈空间足够。 **示例说明**: - 输入: ``` 3 3 0 1 0 2 1 2 ``` 三条边构成环,无桥,输出 `0`。 - 输入: ``` 4 4 0 1 0 2 1 2 2 3 ``` 边 `2-3` 是桥,输出 `1`。 **注意事项**:需处理大量数据时,注意递归深度问题,优先采用非递归DFS或优化实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值