uva10129- Play on Words(单词)

来源:互联网 发布:数据采样 编辑:程序博客网 时间:2024/05/16 09:54

做题还是得站在原有结论的基础上,否则很浪费时间的。就像这次,开始的时候想自己想办法判通路,但是没有成功,后来看了欧拉判断法则,才把程序写出来。

代码如下:

#include <stdio.h>#include <string.h>int str[27][27], visit[27], du[27][2];//用数组记录字母的出度与入度void read(){//读取字符串,记录开头与结尾的字母    int n;    char por, tear, temp;    scanf("%d",&n);    getchar();    while(n--)    {        scanf("%c",&por);        du[por-'a'][1]++;        while((temp=getchar())!='\n')        tear = temp;        du[tear-'a'][0]++;        str[por-'a'][tear-'a'] = 1;    }}void dfs(int s){//深搜,找是否有通路    visit[s] = 1;    for(int i = 0; i < 26; i++)    {        if(str[s][i]&&!visit[i])        dfs(i);    }}int solve(){    int head = -1, tear = -1;    for(int i = 0,count = 0; i < 26; i++)    {//检查出度与入度,是否满足出度与入度相等,否则最多相差1.        if(du[i][0] != du[i][1])        {            if(du[i][0]-du[i][1]>=2&&du[i][0]-du[i][1]<=-2)return 0;            else            {                count++;                if(du[i][1]-du[i][0]==1)  head = i;                else tear = i;            }        }        if(count>2)return 0;//如果出现多个入度与出度相差1的节点,则肯定不能有且只有一条通路    }    if(head==-1&&tear==-1)//如果是欧拉回路的话    {        for(int i = 0; i < 26; i++)        if(du[i][0]){dfs(i); break;}    }    else if(head==-1||tear==-1)return 0;//如果不满足条件“开头节点出度比入度大1和结尾的节点出度比入度小1”    else dfs(head);//否则就从头开始搜索    for(int i = 0; i < 26; i++)    if(((du[i][0]+du[i][1])&&visit[i])||(!(du[i][0]+du[i][1])&&!visit[i]));//看其是否为通路(即有度的节点必须访问到)    else return 0;    return 1;}int main (){    int t;    scanf("%d",&t);    while(t--)    {        memset(str, 0, sizeof(str));        memset(visit,0,sizeof(visit));        memset(du, 0, sizeof(du));        read();        if(solve())puts("Ordering is possible.");        else puts("The door cannot be opened.");    }    return 0;}


原创粉丝点击