NYOJ99 单词拼接
来源:互联网 发布:mac itunes 12.7 铃声 编辑:程序博客网 时间:2024/06/07 03:08
其实上这道题把给的单词转化成一个图,然后考察这个图是否具有一个欧拉回路。
一个图具有欧拉回路的充要条件是这个图是连通的,并且只有0或2个奇点。出度比入度大一的作为起点,出度比入度小一的作为终点。
最后用递归搜索路径
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char s[1000][35];
int F[30], Out[30], In[30], n; // F[]数组为并查集的数组 Out[]为每个字符的出度 In[]为每个字符的入度
int stack[1005], used[1005]; // stack[]数组为保存的路径 usec[]数组为标记是否被选用过
bool flag ;
int find(int x) // 并查集的合并集合
{
return F[x] == x ? x : F[x] = find(F[x]);
}
int cmp(const void *a, const void *b) // 把数组各个特定长度按照升序排序
{
char *p1 = (char *)a;
char *p2 = (char *)b;
return strcmp(p1, p2); // 这是按升序排序 return strcmp(p2, p1) 这是按降序排序
}
void DFS(char first, int cur) //搜索打印方案
{
if(cur==n || flag)
{
flag = 1;
return ;
}
int l = 0, r = n-1, m; //二分搜索查找首字母为first的单词
while(l <= r)
{
m = (l+r)/2;
if(s[m][0] == first)
break;
else if(s[m][0] > first)
r = m-1;
else
l = m+1;
}
while(s[m][0]==first && m>=0) //找到first第一次出现的单词保证字典序最小
m--;
for(int i = m+1; s[i][0] == first; i++)
if(!used[i])
{
stack[cur] = i; // 保存查找到的路径
used[i] = 1;
DFS(s[i][strlen(s[i])-1], cur+1);
if(flag)
return ;
used[i] = 0;
}
}
int main()
{
int T;
// freopen("Input.txt", "r", stdin);
// freopen("O.txt", "w", stdout);
scanf("%d", &T);
while(T--)
{
memset(used, 0, sizeof(used));
memset(Out, 0, sizeof(Out));
memset(In, 0, sizeof(In));
for(int i = 1; i <= 26; i++) //初始化并查集
F[i] = i;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%s", s[i]);
int len = strlen(s[i]);
int q = s[i][0]-'a'+1;
int p = s[i][len-1]-'a'+1;
Out[q]++; //统计每个出现字符的出度
In[p]++; //统计每个出现字符的入度
int x = find(q);
int y = find(p);
if(x != y) // 把属于相同集合的给合并
F[q] = y;
}
qsort(s, n, 35*sizeof(char), cmp);
int count1 = 0, count2 = 0, count3 = 0, count4 = 0, k = 1;
for(int i = 1; i <= 26; i++)
if(Out[i] || In[i])
{
if(F[i] == i)
count1++; //统计这总共有几个集合
if(Out[i]-In[i]==1)
{
count3++; //统计出度比入度大一的个数 这是单词拼接的开始
k = i; //记录开始的位置
}
if(In[i]-Out[i]==1)
count4++; //统计入度比出度大一的个数 这是单词拼接的结束
if(Out[i] != In[i])
count2++;
}
if(count1==1 && count2==count3+count4 && (count2==0 || count2==2))
{
flag = 0;
DFS(k+'a'-1, 0);
for(int i = 0; i < n-1; i++)
printf("%s.", s[stack[i]]);
printf("%s\n", s[stack[n-1]]);
}
else
printf("***\n");
}
return 0;
}
- NYOJ99 单词拼接
- NYOJ99 单词拼接
- nyoj99-单词拼接【欧拉图】
- NYOJ99单词拼接
- NYOJ99单词拼接
- 图论之——单词拼接(nyoj99)(欧拉图+回溯)
- NYOJ99单词拼接(欧拉通路回路,dfs打印路径)
- 单词拼接
- 单词拼接
- 单词拼接
- 单词拼接
- 单词拼接
- 单词拼接 搜索
- nyoj 99 单词拼接
- NYOJ 99 单词拼接
- NYOJ 99 单词拼接
- NYOJ 单词拼接
- NYOJ 99 - 单词拼接
- 一头栽下结束生命的鹰
- cocos2d-x --内存优化之使用16位纹理/NPOT
- java接口与内部类
- 阳光明媚的一天
- kafka环境安装
- NYOJ99 单词拼接
- 细说linux IPC(九):posix消息队列
- NAT穿透(STUN/TURN/ICE/UPnP)
- A+B for Input-Output Practice (V)
- loadrunner中的响应时间与事务响应时间
- 粒子滤波
- 第14讲项目3 多科成绩单
- eclipse注释规则模板设置
- jstl