zoukankan      html  css  js  c++  java
  • LA 3641 (置换 循环的分解) Leonardo's Notebook

    给出一个26个大写字母的置换B,是否存在A2 = B

    每个置换可以看做若干个循环的乘积。我们可以把这些循环看成中UVa 10294的项链, 循环中的数就相当于项链中的珠子。

    A2就相当于将项链旋转了两个珠子间的距离,珠子0、2、4...构成一个循环,一共有gcd(n, 2)个循环,每个循环的长度为n / gcd(n, 2)

    所以当一个循环的长度为奇数的时候,平方以后还是原来的长度;

    当一个循环的长度为偶数的时候,平方以后就会分解为两个长度都等于原来循环长度一半的循环。

    先将置换B分解循环,对于其中长度为奇数2k+1的循环,可以通过相同长度2k+1的循环平方后从A2中得到,也可能是2(2k+1)分解出两个2k+1的循环。

    但是对于长度为偶数2k的循环来说,一定是由长度为4k的循环平方后分解出来的。

    所以如果存在置换A满足A2 = B,则B中长度为偶数的循环节一定为偶数。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 int main()
     5 {
     6     //freopen("in.txt", "r", stdin);
     7 
     8     int T;
     9     scanf("%d", &T);
    10     while(T--)
    11     {
    12         char s[30];
    13         scanf("%s", s);
    14         bool vis[30];
    15         memset(vis, false, sizeof(vis));
    16         int cnt[30];
    17         memset(cnt, 0, sizeof(cnt));
    18 
    19         for(int i = 0; i < 26; i++) if(!vis[i])
    20         {
    21             int j = i;
    22             int n = 0;
    23             do
    24             {
    25                 vis[j] = 1;
    26                 n++;
    27                 j = s[j] - 'A';
    28             }while(j != i);
    29             cnt[n]++;
    30         }
    31 
    32         bool ok = true;
    33         for(int i = 2; i <= 26; i += 2) if(cnt[i] & 1) { ok  = false; break; }
    34         printf("%s
    ", ok ? "Yes" : "No");
    35     }
    36 
    37     return 0;
    38 }
    代码君
  • 相关阅读:
    稀疏数组和队列
    JVM中的GC算法,JVM参数,垃圾收集器分类
    Java虚拟机OOM问题和四大引用问题简述
    DLC双端锁,CAS,ABA问题
    CountDownLanuch,CyclicBarrier,Semaphore,Lock问题
    Callable,阻塞队列,线程池问题
    Android View的绘制机制前世今生---前世
    Android触摸事件传递机制,这一篇就够了
    flutter 与 android 混合开发
    Git 快速极简图文教程 第一篇
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4332131.html
Copyright © 2011-2022 走看看