链接尾随字符的字符串排列

时间:2013-06-11 04:41:59

标签: string algorithm language-agnostic

我正在为一些高中生写一个游戏来学习计算机科学/数学。

但我也陷入了一个我为自己设计的问题,并想看看是否有更有效的方法来解决它。

问题:

单词“Abc”和单词列表[“Cat”,“Tick”,“Apple”,“Orange”,......] 是否有可能在这种情况下构造一个单词链,其中第一个单词的最后一个字符与从单词列表中选择的任何单词的第一个字符相同。这个链是否可以通过给定的单词列表成功构建?如果可能则返回true,否则返回false。

INPUT: boolean lastCharPermutation(String startingWord, String [] wordsList) { .. }

OUTPUT: true for able to complete the combination, false otherwise

例如,

案例#1:"Abc", ["Girl", "King", "Cat", "Dog", "Good", "Tick"] 返回 true ,因为Abc-Cat-Tick-King-Good-Dog-Girl

案例#2:"Abc", ["Tour", "Game", "Cat", "Bridge", "Women", "Man"] 返回 false ,因为Abc-Cat-Tour并停在那里

1 个答案:

答案 0 :(得分:1)

你想要做的是Eulerian Path .. 我在Codechef解决了同样的问题。 如果你想使用这是我的代码.. Plz告诉我你是否需要解释,但很容易理解。

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

int visit[26];
int adj[26][26];
int count=0;

void scc(int i) //Strongly COnnected Component
{
    visit[i]=-1;//visiting
    for(int t=0;t<26;t++)
    {
        if(adj[i][t]>0 && visit[t]==0)//not visited yet
        scc(t);
    }
    visit[i]=1;
    count++;
}

int main()
{
    string in;
    int t,n,k,nv,counta,countb,flag;
    int a[26],b[26];
    cin >> t;
    while(t--)
    {
        cin >> n;
        memset(a,0,26*sizeof(int));
        memset(b,0,26*sizeof(int));
        memset(visit,0,26*sizeof(int));
        memset(adj,0,26*26*sizeof(int));
        k=26;count=0;counta=0;countb=0;flag=0;nv=0;

        while(n > 0)
        {
            n--;
            cin >> in;
            a[in[0]-'a']++;
            b[in[in.size()-1]-'a']++;
            adj[in[0]-'a'][in[in.size()-1]-'a'] = 1;
            adj[in[in.size()-1]-'a'][in[0]-'a'] = 1;
        }

        for(int i=0;i<26;i++)
            if(a[i]>0)
            {
                scc(i);
                break;
            }

        for(int i=0;i<26;i++)
            if(a[i]!=0 || b[i]!=0)
                nv++;

        if(count!=nv)
            flag=1;     

        while(k > 0 && flag!=1  )
        {
            if(a[k-1]-b[k-1] == 1)
                counta++;
            else if(b[k-1]-a[k-1] == 1)
                countb++;
            else if(a[k-1]!=b[k-1])
                flag = 1;
            k--;
        }

        if(flag==0 && counta==countb && ( counta==1 || counta ==0))
            cout << "Ordering is possible." <<endl;
        else
            cout << "The door cannot be opened." <<endl;
    }

    return 0;
}