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.
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).
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".
3 3
3 2 1
1 2 3
Possible
3 2 1
3 3
1 1 1
1 1 1
Ambiguity
3 3
1 2 1
3 3 3
Impossible
In the first sample 3 is replaced by 1 and vice versa, while 2 never changes. The answer exists and is unique.
In the second sample all numbers are replaced by 1, so it is impossible to unambiguously restore the original sequence.
In the third sample fi ≠ 3 for all i, so no sequence ai transforms into such bi and we can say for sure that Spongebob has made a mistake.
思路:
这是一个7:43分的早晨,关于这个提交了15遍最后才过了的题,我想写点什么。
首先想先谈谈自己对CF的认识,由于不让c++和c的格式混用(刚才发现是编译器的问题),至少错了5、6次,教训是立马他妈的去学怎么用cin和cout
好了,学完回来了
然后再说说这个坑爹的题吧,首先理解题意大概就花了能有1h。。。
先说说自己理解后现在的完全抽象版:
就是有两个数列,让你对第二个数列中每个数找到在第一个数列中的位置,如果有哪一项是找不到的,用某个值给他标记出来,那么这个test就是Impossible
如果有两个值找到的pos是相同的,那么这个test的ans就是Ambiguity的
如果没什么问题,即第2个数列的所有元素都能找到唯一且存在的值,那么就输出Possible然后分别输出第二个数列每个数在第一个数列中的位置
再总结几个get的小技巧:
(1)获取某个值在一个数组中的位置,可以让value做为数组下标,然后记录数组的序号。
这个时候如果遇到序号重叠的问题,就要看看之后用到pos的量是否需要这个值
(2)判断一个数组中是否有重复的元素以及数组中各个元素的数量问题,可以专门创建一个数组来表示先前被判断数组元素的数量关系
(3)有n(n大于等于3)个要判断的可能性,可以设置n-1个bool变量,然后一次判断每种可能性
#include <iostream> #include <cstring> using namespace std; int main() { int n,m; int f[100007]; int b[100007]; int a[100007]; int pos[100007]; int num[100007]; while(cin>>n>>m) { /* 错误一:不应该存在的代码 if(n < m) { printf("Impossible "); continue; } */ memset(pos,0,sizeof(pos)); /*错误二:num数组忘记清零*/ memset(num,0,sizeof(num)); int Im = 0; int Am = 0; /*错误三:输入的突然中止*/ for(int i = 1;i <= n;i++){ cin>>f[i]; pos[f[i]] = i; num[f[i]]++; } for(int i = 1;i <= m;i++) { int t; cin>>b[i]; if(num[b[i]] > 1) Am = 1; a[i] = pos[b[i]]; if(a[i] == 0) Im = 1; } if(Im) { cout<<"Impossible"<<endl; continue; } else if(Am) { cout<<"Ambiguity"<<endl; continue; } else { cout<<"Possible"<<endl; for(int i = 1;i <= m-1;i++) cout<<a[i]<<' '; cout<<a[m]<<endl; } } return 0; }