洛谷P1127

14 篇文章 1 订阅

参考的是这篇题解:洛谷P1127
原博客讲的很清楚了,主要就是用单词作为边来建图+字典序排序+深度遍历找欧拉路径
我用下面这个测试用例补充两个地方的解释

3
adc
caa
aaa
  • 为什么要倒序加边
    说白了就是因为是升序排序+深度遍历
    倒序加边是这部分代码
for(int hd,tl,i=n;i>=1;i--){
        hd=a[i][0]-'a'+1;
        tl=a[i][a[i].size()-1]-'a'+1;
        add(hd,tl,i);
    }

排完序后,字符串数组的顺序是这样aaa,adc,caa,如果是正序加边,那么字母a对应的链表是这样的:adc → \rightarrow aaa,然后深度遍历的时候,就是先一直遍历到aaa这条边,然后加到ans数组里,这样就变成了最后输出的反而是字典序最小的单词



  • 为什么在排完序后要设置st=a[1][0]-‘a’+1
    虽然大部分情况下都是这样的:各个字母中,只有1个字母的度为1,1个字母的度为-1,其余字母的度都是0;但是在我提出的这个样例中,各个字母的度都是0,这样,通过下面这个循环来找出起点就不合适了
for(int i=1;i<=26;i++){
        if(d[i]==1){
            st=i;
            break;
        }
    }





最后是我的代码

#include <bits/stdc++.h>

using namespace std;

const int maxn=1005;

int lans;

typedef struct e{
  int op;
  int to;
  int nxt;
}e;

e edge[maxn];
int d[30];//存储各个字母的度
int head[30];
bool use[maxn];

int tot;
void add(int x,int y,int op){
    tot++;
    edge[tot].op=op;
    edge[tot].to=y;
    edge[tot].nxt=head[x];
    head[x]=tot;
    d[x]++;
    d[y]--;
}

string ans[maxn];
string a[maxn];
void dfs(int st){
    for(int i=head[st];i;i=edge[i].nxt){
        if(!use[edge[i].op]){
            use[edge[i].op]=1;
            dfs(edge[i].to);
            lans++;
            ans[lans]=a[edge[i].op];
        }
    }
}

int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }

    sort(a+1,a+n+1);

    for(int hd,tl,i=n;i>=1;i--){
        hd=a[i][0]-'a'+1;
        tl=a[i][a[i].size()-1]-'a'+1;
        add(hd,tl,i);
    }

    int st;

    st=a[1][0]-'a'+1;

    for(int i=1;i<=26;i++){
        if(d[i]==1){
            st=i;
            break;
        }
    }

    dfs(st);

    for(int i=1;i<=n;i++){
        if(use[i]==0){
            printf("***");
            return 0;
        }
    }

    for(int i=lans;i>1;i--){
        cout<<ans[i]<<".";
    }

    cout<<ans[1];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值