开篇,UVA 755 && POJ 1002 487--3279 (Trie + DFS / sort)

博客第一篇写在11月1号,果然die die die die die alone~

一道不太难的题,白书里被放到排序这一节,半年前用快排A过一次,但是现在做的时候发现可以用字典树加深搜,于是乐呵呵的开始敲了,后来被卡了两天,一直以为算法错了,最后发现是输出答案时忘了回溯,这问题之前没怎么注意过,也算不小的收获。

字典树A了之后换sort来写,没想到快排效率更高,时间减少了一半,在POJ上A了之后重新在UVA上提交,居然WA了,调试半个小时,发现是变长数组的问题,看来UVA上的编译器对c99的支持不太好。

虽然有点水题的感觉,但是收获不小:

1.DFS处理答案的时候要考虑是否回溯

2.更深理解哈希

3.VLA慎用

  487-3279 

Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or phrase. For example, you can call the University of Waterloo by dialing the memorable TUT-GLOP. Sometimes only part of the number is used to spell a word. When you get back to your hotel tonight you can order a pizza from Gino's by dialing 310-GINO. Another way to make a telephone number memorable is to group the digits in a memorable way. You could order your pizza from Pizza Hut by calling their ``three tens'' number 3-10-10-10.

The standard form of a telephone number is seven decimal digits with a hyphen between the third and fourth digits (e.g. 888-1200). The keypad of a phone supplies the mapping of letters to numbers, as follows:

A, B, and C map to 2

D, E, and F map to 3

G, H, and I map to 4

J, K, and L map to 5

M, N, and O map to 6

P, R, and S map to 7

T, U, and V map to 8

W, X, and Y map to 9

There is no mapping for Q or Z. Hyphens are not dialed, and can be added and removed as necessary. The standard form of TUT-GLOP is 888-4567, the standard form of 310-GINO is 310-4466, and the standard form of 3-10-10-10 is 310-1010.

Two telephone numbers are equivalent if they have the same standard form. (They dial the same number.)

Your company is compiling a directory of telephone numbers from local businesses. As part of the quality control process you want to check that no two (or more) businesses in the directory have the same telephone number.

Input

The first line of the input contains the number of datasets in the input. A blank line follows. The first line of each dataset specifies the number of telephone numbers in the directory (up to 100,000) as a positive integer alone on the line. The remaining lines list the telephone numbers in the directory, with each number alone on a line. Each telephone number consists of a string composed of decimal digits, uppercase letters (excluding Q and Z) and hyphens. Exactly seven of the characters in the string will be digits or letters. There's a blank line between datasets.

Output

Generate a line of output for each telephone number that appears more than once in any form. The line should give the telephone number in standard form, followed by a space, followed by the number of times the telephone number appears in the directory. Arrange the output lines by telephone number in ascending lexicographical order. If there are no duplicates in the input print the line:

No duplicates.

Print a blank line between datasets.

Sample Input

1

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3

UVA上的代码如下,POJ上的和UVA有点不同,是单组输入,但算法是一样的

 #include<stdio.h>
#include<stdlib.h>
#include<string.h> struct trie
{
struct trie * next[];
int count;
};
struct trie * ROOT = NULL;
char RULE[] = {'','','','','','','','','','','','','','','','','','','','','','','','','',''};
char BOX[];
int FLAG; void insert(char * s);
void dfs(struct trie * temp,int len);
int main(void)
{
int t,n,len;
char s[],number[]; scanf("%d",&t);
while(t --)
{
FLAG = ;
ROOT = (struct trie *)malloc(sizeof(struct trie));
for(int i = ;i < ;i ++)
ROOT -> next[i] = NULL;
ROOT -> count = ; scanf("%d",&n);
while(n --)
{
len = ; scanf("%s",s);
for(int i = ;s[i];i ++) //转化为纯数字形式
{
if(s[i] >= '' && s[i] <= '')
number[len ++] = s[i];
else if(s[i] >= 'A' && s[i] <= 'Z')
number[len ++] = RULE[s[i] - 'A'];
}
number[len] = '\0';
insert(number);
}
dfs(ROOT,);
if(FLAG)
puts("No duplicates.");
puts("");
} return ;
} void insert(char * s) //trie插入函数
{
struct trie * temp = ROOT; for(int i = ;s[i];i ++)
if(temp -> next[s[i] - ''])
temp = temp -> next[s[i] - ''];
else
{
temp -> next[s[i] - ''] = (struct trie *)malloc(sizeof(struct trie));
for(int j = ;j < ;j ++)
temp -> next[s[i] - ''] -> next[j] = NULL;
temp -> next[s[i] - ''] -> count = ; temp = temp -> next[s[i] - ''];
}
temp -> count ++; return ;
} void dfs(struct trie * temp,int len) //深搜输出
{
for(int i = ;i < ;i ++)
if(temp -> next[i])
{
BOX[len] = i + '';
len ++;
if(temp -> next[i] -> count >= )
{
FLAG = ;
BOX[len] = '\0';
for(int j = ;BOX[j];j ++)
{
if(j == )
putchar('-');
printf("%c",BOX[j]);
}
printf(" %d\n",temp -> next[i] -> count);
len --; //注意回溯 continue;
}
dfs(temp -> next[i],len);
len --;
} return ;
}

Trie + DFS

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <algorithm>
using namespace std; int RULE[] = {,,,,,,,,,,,,,,,,,,,,,,,,,}; int main(void)
{
int * ans;
int t,n,sum,flag,times,count,i,j,k;
char temp[]; scanf("%d",&t);
while(t --)
{
count = ;
scanf("%d",&n); ans = (int *)malloc(sizeof(int) * n); //如果在UVA上用ans[n]的形式便会WA
while(n --)
{
scanf("%s",temp);
for(i = sum = ;temp[i];i ++) //转化为纯数字形式(哈希)
{
if(temp[i] >= '' && temp[i] <= '')
{
sum *= ;
sum += (temp[i] - '');
}
else if(temp[i] >= 'A' && temp[i] <= 'Z')
{
sum *= ;
sum += (RULE[temp[i] - 'A']);
}
}
ans[count ++] = sum;
}
sort(ans,ans + count); //全部存入数组后排序 for(i = flag = ;i < count - ;i ++)
{
times = ; while(ans[i] == ans[i + ])
{
times ++;
i ++;
}
if(times > )
{
flag = ;
printf("%03d-%04d %d\n",ans[i] / ,ans[i] % ,times); //除法:截去后n位 求余:计算出后n位
}
}
if(!flag)
puts("No duplicates.");
if(t)
puts("");
} return ;
}

sort

上一篇:MyEclipse中好用的快捷键汇总


下一篇:Windows Server 2012四大版本介绍