问题 : 成语接龙
时间限制: 1 Sec 内存限制: 32 MB
http://218.198.32.182/problem.php?cid=1070&pid=3
题目描述
小明在玩成语接龙的游戏。成语接龙的规则是,如果成语A的最后一个汉字与成语B的第一个汉字相同,那么成语B就可以接到成语A的后面。
小明现在手上有一本成语词典,每次他都得花费一定时间来从当前的成语查到下一个可以接在后面的成语。
现在给你一个成语列表,请你计算从列表中的第一个成语开始,到接到列表中的最后一个成语最少需要多长时间。
小明现在手上有一本成语词典,每次他都得花费一定时间来从当前的成语查到下一个可以接在后面的成语。
现在给你一个成语列表,请你计算从列表中的第一个成语开始,到接到列表中的最后一个成语最少需要多长时间。
输入
输入包含多组测试数据。
每组输入第一行是一个整数N(0<N<1000),表示成语列表的长度。
接下来N行,每行先输入一个整数T,再输入一个字符串S。
S表示一条成语,T表示小明从S查到下一个成语所花费的时间。
每条成语由至少3个汉字组成,每个汉字由4个十六进制数(0~9和A~F)组成。
当N=0时,输入结束。
每组输入第一行是一个整数N(0<N<1000),表示成语列表的长度。
接下来N行,每行先输入一个整数T,再输入一个字符串S。
S表示一条成语,T表示小明从S查到下一个成语所花费的时间。
每条成语由至少3个汉字组成,每个汉字由4个十六进制数(0~9和A~F)组成。
当N=0时,输入结束。
输出
对于每组输入,输出从列表中的第一个成语开始,到接到列表中的最后一个成语需要的最少时间。
如果无法连接到列表中的最后一个成语,则输出-1。
如果无法连接到列表中的最后一个成语,则输出-1。
样例输入
5
5 12345978ABCD2341
5 23415608ACBD3412
7 34125678AEFD4123
15 23415673ACC34123
4 41235673FBCD2156
2
20 12345678ABCD
30 DCBF5432167D
0
样例输出
17
-1
就是一个深搜,就是取值的时候复杂点,看了代码你就懂了。
# include <stdio.h>
# include <string.h>
struct qwe
{
int time; //时间
char tail[10]; //成语的头部
char head[10]; //成语的尾部
char s[100]; //成语
};
int book[1001], n, min;
struct qwe a[1001];
void dfs(int cur, int step)
{
int i;
if (strcmp(a[cur].head, a[n-1].tail) == 0) // 看是否读到了最后一个
{
if (step < min)
min = step;
return;
}
for (i = 0; i < n; i ++)
{
if (book[i] == 0 && strcmp(a[cur].head, a[i].tail) == 0) // 判断是否头尾相等
{
book[i] = 1;
dfs(i, step+a[i].time);
book[i] = 0;
}
}
return;
}
int main(void)
{
int i, c, d, j;
while (~ scanf("%d", &n))
{
if (n == 0)
break;
if (n == 1)
{
printf("0\n");
continue;
}
memset(book, 0, sizeof(book));
memset(a, 0, sizeof(a));
c = 0;
for (i = 0; i < n; i ++)
{
scanf("%d %s", &a[i].time, a[i].s);
for (j = 0; j <= 3; j ++)
{
a[c].tail[j] = a[i].s[j];
}// 将每一个成语的前4位存起来
d = 3;
for (j = strlen(a[i].s)-1; j >= strlen(a[i].s)-4; j --)
{
a[c].head[d] = a[i].s[j];
d --;
}// 将每一个成语的后4位存起来
c ++;
}
book[0] = 1, min = 99999999;
dfs(0, a[0].time);
if (min == 99999999)
printf("-1\n");
else
printf("%d\n", min);
}
return 0;
}