@xiaoziyao
2020-06-08T19:03:44.000000Z
字数 1054
阅读 977
解题报告
CF1365C Rotation Matching解题报告:
一开始看到这道题是不想做的:
这个翻译。。。
最后还是看了一下英文题面,发现真的水。。。然后一下子就做出来了。
题意:给定两个排列与,可以将循环移动若干次(一次循环移动指将变为),求排列排列最多能有几个匹配(即相同位置的数相同)。
数据范围:。
分析数据范围,这道题明显是,最多带上一两个或一个根号。
考虑循环移动的意义——排列内数字的的相对位置不会改变(将环拆成链来看),同时因为排列不会移动,因此对于原排列与经过若干次操作的排列,存在一个数()使,即对于任意一个数(),在中的位置与在中的位置的距离(注意,这里的距离也是将环拆成链看的距离,后面的距离也是指这种距离)都是相等的。
因此,对于任意一个数(),在中的位置与在中的位置的距离就是使这两个数匹配的移动次数。
于是我们可以记录到所有数在排列与排列中的位置,然后计算他们之间的距离,即使它们匹配的移动次数,并记录每个移动次数的出现次数,最大的出现次数便是答案了。
#include<stdio.h>
const int maxn=1000005;
int i,j,k,m,n,ans;
int a[maxn],b[maxn],c[maxn],d[maxn],cnt[maxn];
inline int max(int a,int b){
return a>b? a:b;
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
c[a[i]]=i;
}
for(i=1;i<=n;i++){
scanf("%d",&b[i]);
d[b[i]]=i;
}
for(i=1;i<=n;i++)
cnt[(c[i]-d[i]+n)%n]++;
for(i=0;i<n;i++)
ans=max(ans,cnt[i]);
printf("%d\n",ans);
return 0;
}