奶牛摄影

139 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

题目信息

奶牛们今天非常调皮。

农夫约翰想给站成一排的奶牛拍一张照片,但是在他有机会拍下照片之前,奶牛一直在移动。

具体的说,约翰有 N 头奶牛,编号 1∼N。

约翰想拍一张奶牛以特定顺序站成一排的照片,这个顺序可以用数组 A[1..N] 来表示,其中 A[j]表示排列中第 jj 头奶牛的编号。

他按这个顺序将奶牛排成一排,但就在他按下相机上的按钮拍摄照片之前,最多一头奶牛移动到了新的位置上。

更准确地说,要么没有奶牛移动,要么一头奶牛离开她在队列中的当前位置,然后重新插入到队列中的新位置。

约翰非常沮丧,但并没有灰心,他再次按照数组 A 的顺序,排列了他的奶牛。

但是,就在他再次拍照之前,又有最多一头奶牛移动到了队列中的新位置。

在约翰放弃之前,上面的过程一共重复了五次,拍下了五张照片。

给定每张照片的内容,请你推断出最初的预定顺序 A。

每张照片显示的都是在预定顺序下,最多一头奶牛移动后的奶牛排列顺序。

每头奶牛最多只会在拍摄一张照片时移动,如果一头奶牛在拍摄一张照片时移动了,那么她就不会在拍摄其他照片时主动移动。(尽管由于其他奶牛的移动,她最终可能会处于不同的位置)

输入格式

第一行包含整数 N,表示奶牛数量。

接下来 5N 行,每 N 行描述一张照片中的奶牛顺序,每行包含一个奶牛的编号。

输出格式

共 N 行,输出预定顺序 A,每行输出一个奶牛编号。 可以证明,本题解唯一。

数据范围

1≤N≤20000

输入样例:

5
1 
2 
3 
4 
5
2
1
3
4
5
3
1
2
4
5
4
1
2
3
5
5
1
2
3
4

输出样例:

1
2
3
4
5

思路

  • 一个很关键的点就在于每个奶牛只会移动一次
  • 所以每次只考虑两个奶牛A<BA<B的话;
  • 我们移动其他奶牛是不会改变ABAB的前后关系的
  • 只有把BB移到AA前面,或者把AA移到BB后面才会改变ABAB前后关系(最多两种情况)
  • 还有其他3次均是A<BA<B
  • 所以次数可以判断两个数,哪个在前,哪个在后

代码

#include<bits/stdc++.h>
using namespace std;
​
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    unordered_map<int, int> mp[5];
    int n; cin >> n;
    for(int i = 0; i < 5; i++)
        for(int j = 0, x; j < n; j++) cin >> x, mp[i][x] = j;
​
    vector<int> v(n);
    for(int i = 0; i < n; i++) v[i] = i + 1;
    sort(v.begin(), v.end(), [&](int a, int b){
        int cnt = 0;
        for(int i = 0; i < 5; i++) cnt += (mp[i][a] < mp[i][b]);
        return cnt >= 3;
    });
    for(int i : v) cout << i << '\n';
​
    return 0;
}
​