Codeforces Round #332 (Div. 2) B. Spongebob and Joke

. Spongebob and Joke
Time Limit: 20 Sec
Memory Limit: 256 MB
Description
While Patrick was gone shopping, Spongebob decided to play a little trick on his friend. The naughty Sponge browsed through Patrick’s personal stuff and found a sequence a1, a2, …, am of length m, consisting of integers from 1 to n, not necessarily distinct. Then he picked some sequence f1, f2, …, fn of length n and for each number ai got number bi = fai. To finish the prank he erased the initial sequence ai.
It’s hard to express how sad Patrick was when he returned home from shopping! We will just say that Spongebob immediately got really sorry about what he has done and he is now trying to restore the original sequence. Help him do this or determine that this is impossible.
Input
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 100 000) — the lengths of sequences fi and bi respectively.
The second line contains n integers, determining sequence f1, f2, …, fn (1 ≤ fi ≤ n).
The last line contains m integers, determining sequence b1, b2, …, bm (1 ≤ bi ≤ n).
Output
Print “Possible” if there is exactly one sequence ai, such that bi = fai for all i from 1 to m. Then print m integers a1, a2, …, am.
If there are multiple suitable sequences ai, print “Ambiguity”.
If Spongebob has made a mistake in his calculations and no suitable sequence ai exists, print “Impossible”.
Sample Input
3 3
3 2 1
1 2 3
Sample Output
Possible
3 2 1

题意:
给定n个f[i],m个b[i],能否找到m个a[i],使得b[i]=f[a[i]]?
如果不能输出Impossible, 如果能找到不止一个a[i],输出Ambiguity, 如果只能找到一个,输出Possible 然后换行输出这一个a[i]

思路:
根据式子b[i]=f[a[i]]可以得到信息:
1、每一个b[i]必然存在一个f[a[i]]与之对应,每一个f[a[i]]必然存在一个a[i]与之对应。
简单来说就是有b必有f,有f必有a。
2、如何判断是否只存在一个a数组,存在多个a数组,不存在a数组:根据1
1)如果有b没有f,即存在b[i]但没有一个f与之对应,那就不存在a数组
2)有b有f,即每个b[i]都有f与之对应,且f下只有一个a[i]与之对应,possible
3) 有b有f,即每个b[i]都有f与之对应,且f下有多个a[i]与之对应,Ambiguity

发现2中关键是找到f与a的对应,b和f 的对应。关键找到数据结构或者算法。
这里写图片描述
这里写图片描述这里写图片描述

如图a possible 图b impossible 图c ambiguity

从图C可以得到启发,用vector结构来建立f和a的对应:
for(int i=0;i

#include<iostream>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
#define maxn 100005
int a[maxn],f[maxn],b[maxn];
vector<int> Q[maxn];
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
         for(int i=0;i<n;i++)
        scanf("%d",&f[i]);
    for(int i=0;i<m;i++)
        scanf("%d",&b[i]);
    for(int i=0;i<n;i++)
        Q[f[i]].push_back(i);
    int flag = 0;
    for(int i=0;i<m;i++)
    {
        if(Q[b[i]].size()==0){
             cout<<"Impossible"<<endl;
              return 0;
        }
        if(Q[b[i]].size()>1)
            flag = 1;
    }
    if(flag == 1){
        cout<<"Ambiguity"<<endl;
         return 0;
    }
    cout<<"Possible"<<endl;
    for(int i=0;i<m;i++)
        printf("%d ",Q[b[i]][0]+1);
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值