题意:
送礼物,每个人都要送给别人礼物和收到别人礼物,一开始给你个序列,已知其中一些序列,然后求满足情况的完整序列
题解
这个题是个思路题,唉,我以为是构造环,写了一个
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]);
}
}