[关闭]
@xiaoziyao 2020-06-08T19:03:44.000000Z 字数 1054 阅读 977

CF1365C Rotation Matching解题报告

解题报告


CF1365C Rotation Matching解题报告:

更好的阅读体验

前言

一开始看到这道题是不想做的:

这个翻译。。。

最后还是看了一下英文题面,发现真的水。。。然后一下子就做出来了。

题意

题意:给定两个排列,可以将循环移动若干次(一次循环移动指将变为),求排列排列最多能有几个匹配(即相同位置的数相同)。
数据范围:

分析

分析数据范围,这道题明显是,最多带上一两个或一个根号。

考虑循环移动的意义——排列内数字的的相对位置不会改变(将环拆成链来看),同时因为排列不会移动,因此对于原排列与经过若干次操作的排列,存在一个数)使,即对于任意一个数),中的位置与在中的位置的距离(注意,这里的距离也是将环拆成链看的距离,后面的距离也是指这种距离)都是相等的。

因此,对于任意一个数),中的位置与中的位置的距离就是使这两个数匹配的移动次数。

于是我们可以记录所有数在排列与排列中的位置,然后计算他们之间的距离,即使它们匹配的移动次数,并记录每个移动次数的出现次数,最大的出现次数便是答案了。

代码

  1. #include<stdio.h>
  2. const int maxn=1000005;
  3. int i,j,k,m,n,ans;
  4. int a[maxn],b[maxn],c[maxn],d[maxn],cnt[maxn];
  5. inline int max(int a,int b){
  6. return a>b? a:b;
  7. }
  8. int main(){
  9. scanf("%d",&n);
  10. for(i=1;i<=n;i++){
  11. scanf("%d",&a[i]);
  12. c[a[i]]=i;
  13. }
  14. for(i=1;i<=n;i++){
  15. scanf("%d",&b[i]);
  16. d[b[i]]=i;
  17. }
  18. for(i=1;i<=n;i++)
  19. cnt[(c[i]-d[i]+n)%n]++;
  20. for(i=0;i<n;i++)
  21. ans=max(ans,cnt[i]);
  22. printf("%d\n",ans);
  23. return 0;
  24. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注