ACM必做50题的解题-快速查找(B-Search, Hash and so on)

2019-03-11 15:44

POJ 2503 Babelfish

题目大意很简单,就是给你字典的对应信息,然后给你查询条件要求你输出字典查询结果,如果字符串没有在字典中则输出\。

恩,学到了一个新的函数bsearch(),可以进行二分查找。先对字典使用qsort排序然后再使用bsearch()查找字符串即可。

还学到了一个输入函数sscanf(),可以从一个字符串中读取内容,格式如下 sscanf (string str, string format [, string var1...])

#include #include #include

typedef struct {

char en[11]; char fn[11]; }dict;

dict a[100001];

/* 定义qsort比较函数 */

int q_cmp(const void * a,const void *b) {

return strcmp(((dict*)a)->fn, ((dict*)b)->fn); }

/* 定义bsearch比较函数 */

int b_cmp(const void* a, const void* b) {

return strcmp((char*)a, ((dict*)b)->fn); }

int main() {

char str[30]; int i, sign; dict *p;

i = 0;

/* 查询标记记为\未开始\ sign = 1;

/* 读取字符串直到文件结束 */

while(gets(str)) {

/* 遇到空行则开始排序字典 */ if (str[0] == '\\0') {

/* 查询标记记为\开始\ sign = 0;

qsort(a, i, sizeof(dict), q_cmp); continue; }

/* 查询未开始时读取字典信息 */ if (sign) {

/* 使用sscanf从str中读取查询要求 */ sscanf(str, \ i++; }

/* 查询开始时进行查询 */ else {

/* 二分查找指定字符串 */

p = (dict*) bsearch(str, a, i, sizeof(dict), b_cmp); /* 找到则输出结果 */ if (p) {

puts(p->en); }

/* 找不到输出\ else {

puts(\ } } }

//system(\ return 0; }

POJ 2513 Colored Sticks 欧拉通路+并查集+trie树

这道题大意是:已知有n根木棒,每个木棒有两种颜色表示两端,问:能不能将所有的木棒

连接成一条直线(连接处颜色相同)。 可以考虑无向图的欧拉通路问题:将每种颜色看成图中的一个节点,木棒看作连接节点的边,于是判断两点:

1,每种颜色(节点)的度 2,是否为连通图

首先,每种颜色的度可以通过每条木棒的两端颜色的累积得到,问题是,每种颜色都是字符串,怎么关联每种颜色和度呢?

最容易想到的是Hash,这肯定是可行的。例如degree [ hash(red) ]=5。表示颜色为红色的度为5。

但是,既然提示用trie树来做,那么trie树的节点的数据域就可以保存每种颜色的id(相当于分配的hash值,可以通过一个全局变量自增产生),这样经过将每种颜色字符串插入到tree中以后,通过trie树的search操作就能高效的获取每种颜色对应的id,没插入一种颜色,为其产生一个id,只需要注意相同颜色插入时的处理即可。

其次,判断无向图是否连通可以使用并查集来判定:经过n-1各union操作后,所有节点都在一个集合(树形结构表示集合的话,即所有节点的父节点(集合代表)都一样)。由于每种颜色是由字符串来标示的,每个集合保存颜色对应的唯一id。 通过上面两个步骤的判定,就可以得出结果。

#include #include using namespace std;

const int max_size=500001; char s1[11],s2[11]; int p[max_size]; int r[max_size];

int degree[max_size]; int num=1;

struct TreeNode {

int id;//the id of the string TreeNode * next[27]; TreeNode () {

id=0;

for(int i=0;i<27;i++) next[i]=NULL; } };

TreeNode * root;

void insert(char *s ,TreeNode * root) {

TreeNode *p = root; int i = 0;

int l = strlen(s); for(i=0;i

if(p->next[s[i]-'a']==NULL)

p->next[s[i]-'a']=new TreeNode; p=p->next[s[i]-'a']; }

if(p->id==0)//first insert p->id = num++; }

int search(char *s,TreeNode *root) {

TreeNode * p = root; if(p==NULL)

return -1; int i=0;

int l = strlen(s); for(i=0;i

if(p->next[s[i]-'a']==NULL) return -1; else

p=p->next[s[i]-'a']; }

return p->id; }

void make_set(int x) {

p[x]=x; r[x]=1; }

int find_set(int x) {

if(p[x]!=x)

p[x]=find_set(p[x]); return p[x]; }

void union_set(int x,int y) {

if(r[x]>r[y]) p[y]=x; else if(r[x]

{

r[y]++; p[x]=y; } }

int main() {

root = new TreeNode; memset(p,0,sizeof(p));

memset(degree,0,sizeof(degree)); while(scanf(\ {

insert(s1,root); insert(s2,root);

int id1 = search(s1,root); int id2 = search(s2,root); degree[id1]++; degree[id2]++; if(p[id1]==0)

make_set(id1); if(p[id2]==0)

make_set(id2);

union_set(find_set(id1),find_set(id2)); }

int i = 0; int sum=0;

//if the num of nodes whose degree is odd are more than 2. for(i=1;i

if(degree[i]%2!=0)sum++; if(sum>2) {

cout<<\ return 0; } }

//if the g is joint. for(i=1;i

if(find_set(i) != find_set(1)) {

cout<<\ return 0 ; }

cout<<\


ACM必做50题的解题-快速查找(B-Search, Hash and so on).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:linux下行为记录监控

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: