周日 毫无准备地被拉去中南打了一次湖南多校现场赛
书包里装的是两本高数书hhh
四个多小时也就做了一题
还是靠队友 (宋会长nb (逃~
Description
给定两个1~n的排列A, B。每次可以把A的最后一个数取出,插入到A的任何一个位置(最前面或者任何两个数中间)。 问最少几次可以把A转化为B。
Input
第一行为一个整数n。 第二行为1~n的一个排列,表示A。 第三行为1~n的一个排列,表示B。
Output
一个整数即最少操作次数。
Sample Input
5 1 5 2 3 4 1 2 3 4 5
Sample Output
3
Hint
30%:n <= 100
50%:n <= 1000
100%: n <= 200000
题意:
两个含有n个数的数组,将第一个数组进行多次变换,即将最后一个数放入前面任意一个位置,若干次操作后,得到第二行的数组。
理解:
因为最后的数可以放到其前面的任意位置,所以,关键在于两个数组相比第一个不同的数字。
例1:
5
1 5 3 2 4
1 2 3 4 5
这是题目给出的样例,两数组间第一个不同数字是第二组数字,即表示 从第二组开始的数字都需要重新排列。
(答案为3)
例2:
5
2 3 4 5 1
1 2 3 4 5
这是我自己出的样例,特殊之处在于,只要将最后的 1 插入到数组的最前面就可以完成转化,即移动一次。
(答案为1)
例3:
5
3 4 1 2 5
1 2 3 4 5
又给了一个我自己出的样例,将例2与例3结合起来看,可以发现:在第一组不同的数组之后 若之后的数据存在相对位置相同的情况时,要减去这几种情况。比如:例 2 的 2 3 4 5 以及例 2 的 3 4
下面放一下队友的代码:
#include <cstdio>
#include <cstring>
using namespace std;const int SIZE = 2e5+10;
int a1[SIZE], a2[SIZE], a3[SIZE];
int main()
{int n, jl = 0, js = 0;memset(a1, 0, sizeof(a1));memset(a2, 0, sizeof(a2));memset(a3, 0, sizeof(a3));scanf("%d", &n);for(int i = 1; i <= n; i++){scanf("%d", a1+i);}for(int i = 1; i <= n; i++){scanf("%d", a2+i);a3[a2[i]] = i;}int j1, j2;for(int i = 1; i <= n; i++){if(a1[i] != a2[i]){j1 = i+1, j2 = a3[a1[i+1]];jl = i;break;}}if(j1 < j2){for(int i = j2; i <= n; i++){if(a1[j1] == a2[i]){j1++;js++;}}}printf("%d\n", n-jl-js);return 0;
}/**********************************************************************Problem: 1243User: multi2018team036Language: C++Result: ACTime:128 msMemory:3464 kb
**********************************************************************/
还好我们没放弃啊
最后终于A了一题...(在离比赛结束还有20分钟的时候)
无意间看到别人的博客 思想稍微有点不同
也想放一下:https://blog.csdn.net/Abandoninged/article/details/80560207