CodeForces - 1255C League of Leesins(思维+处理)

题目链接https://vjudge.net/contest/344327#problem/C
在这里插入图片描述
翻译
给定一个排列(1~n),三个相连的数组成一个三元组,那么长度为n的排列,可以组成n-2个三元组
例如1 2 3 4 5可以组成(1 2 3)(2 3 4)(3 4 5)三个三元组。
刚开始输入一个n,接下来给定n-2个三元组,可是这n-2个三元组,任意改变顺序,内部的三个数也任意改变顺序(但是保证这三个数仍然是相连的)。求一个符合条件的排列。
分析
对于n-2个三元组,一定有两个数出现的次数为1,这两个数一定是排列的开头和结尾。
一定有两个数出现的次数为2,这两个数一定是排列开头的第二个数和结尾倒数第二个数。
别的数出现的次数为3次,且出现的三元组一定为3个。
对于每一个三元组,变换有3种。
找到开头(x)和第二个数(y)所在的三元组(另一个数为z),找到下一个三元组满足y和z在其中,同时保证另一个数不是x。
代码

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e5+10;
vector<int>v[N];
int book[N],co[N];
int main()
{
    int n;
    memset(book,0,sizeof(book));
    memset(co,0,sizeof(co));
    scanf("%d",&n);
    for(int i=1,x,y,z; i<=n-2; i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        v[x].push_back(y),v[x].push_back(z);
        v[y].push_back(x),v[y].push_back(z);
        v[z].push_back(x),v[z].push_back(y);
        book[x]++,book[y]++,book[z]++;
    }
    int t1,t2;
    for(int i=1; i<=n; i++)/*找到开头*/
    {
        if(book[i]==1)
        {
            co[i]=1;
            t1=i;
            break;
        }
    }
    for(int i=0;i<v[t1].size();i++)
    {
        if(book[v[t1][i]]==2)
        {
            t2=v[t1][i];
            co[v[t1][i]]=1;
            break;
        }
    }
    printf("%d %d",t1,t2);
    for(int i=3;i<=n;i++)
    {
        int tab;
        for(int j=0;j<v[t1].size();j++)
        {
            if(!co[v[t1][j]])
            {
                printf(" %d",v[t1][j]);
                co[v[t1][j]]=1;
                tab=v[t1][j];
                break;
            }
        }
        t1=t2;
        t2=tab;
    }
    return 0;
}

在这里插入图片描述

发布了165 篇原创文章 · 获赞 6 · 访问量 5078

猜你喜欢

转载自blog.csdn.net/lylzsx20172018/article/details/103193969