Codeforces Round #611 (Div. 3) C:Friends and Girls

题目链接

题意:

送礼物,每个人都要送给别人礼物和收到别人礼物,一开始给你个序列,已知其中一些序列,然后求满足情况的完整序列

题解

这个题是个思路题,唉,我以为是构造环,写了一个bfs(),令出度入度匹配,然而不幸TLE,真正的思路是,点只要不在原位置,就可以

TLE代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+5;
int in[maxn],out[maxn],vis[maxn],n;
void bfs()
{
    queue<int>q;
    for(int i=1; i<=n; i++)
    {
        if(!out[i]&&!in[i])
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int st=q.front();
        q.pop();
        if(out[st]||in[st])
            continue;
        for(int i=1; i<=n; i++)
        {
            if(st!=i&&!in[i])
            {
                out[st]++;
                in[i]++;
                vis[st]=i;
                break;
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(!out[i])
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int st=q.front();
        q.pop();
        if(out[st]&&in[st])
            continue;
        for(int i=1; i<=n; i++)
        {
            if(st!=i&&!in[i])
            {
                out[st]++;
                in[i]++;
                vis[st]=i;
                break;
            }
        }
    }
}
int main()
{
    int x;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&x);
        if(x)
        {
            vis[i]=x;
            in[x]++;
            out[i]++;
        }
    }
    bfs();
    for(int i=1; i<=n; i++)
    {
        if(i!=n)
            printf("%d ",vis[i]);
        else
            printf("%d\n",vis[i]);
    }
}

AC代码:

利用vector,将没有匹配的位置,和数记录下来,然后如果数和位置重叠,就让,数和下一个位置的数交换,因为是环,所以取余即可,交换位置,和交换数性质一样,只要保证一个为定值即可

AC代码交换位置

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
bool fla[maxn];
int s[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&s[i]);
        fla[s[i]]=true;//代表s[i]存在
    }
    vector<int>a,b;
    for(int i=1;i<=n;i++)
    {
        if(!fla[i])//判断数是否存在
        {
            a.push_back(i);
        }
        if(!s[i])//判断位置是否存在
        {
            b.push_back(i);
        }
    }
    int len=a.size();//数和位置数量一样
    for(int i=0;i<len;i++)
    {
        if(a[i]==b[i])
        {
            swap(b[i],b[(i+1)%len]);
        }
    }
    for(int i=0;i<len;i++)
    {
        s[b[i]]=a[i];
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d ",s[i]);
    }
}

AC代码:交换数

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
bool fla[maxn];
int s[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&s[i]);
        fla[s[i]]=true;//代表s[i]存在
    }
    vector<int>a,b;
    for(int i=1;i<=n;i++)
    {
        if(!fla[i])//判断数是否存在
        {
            a.push_back(i);
        }
        if(!s[i])//判断位置是否存在
        {
            b.push_back(i);
        }
    }
    int len=a.size();//数和位置数量一样
    for(int i=0;i<len;i++)
    {
        if(a[i]==b[i])
        {
            swap(a[i],a[(i+1)%len]);
        }
    }
    for(int i=0;i<len;i++)
    {
        s[b[i]]=a[i];
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d ",s[i]);
    }
}
发布了205 篇原创文章 · 获赞 12 · 访问量 8507

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/103890731