周日 毫无准备地被拉去中南打了一次湖南多校现场赛
书包里装的是两本高数书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: 1243
User: multi2018team036
Language: C++
Result: AC
Time:128 ms
Memory:3464 kb
**********************************************************************/
还好我们没放弃啊
最后终于A了一题...(在离比赛结束还有20分钟的时候)
无意间看到别人的博客 思想稍微有点不同
也想放一下:https://blog.csdn.net/Abandoninged/article/details/80560207