zoukankan      html  css  js  c++  java
  • LA 3641 Leonardo的笔记本 & UVA 11077 排列统计

    LA 3641 Leonardo的笔记本

    题目

    给出26个大写字母的置换B,问是否存在要给置换A,使得 (A^2 = B)

    分析

    将A分解为几个循环,可以观察经过乘积运算得到(A^2)后,循环有什么不同。将循环画成一个环,给他们标号(0,1,cdots,n-1), 0号指向1号,n-1号指向1号。如果 n 是奇数,那么可以发现(A^2)中,0号指向了2号,2号指向了4号...n-1号指向了1号,1号指向3号...n-2号指向0号,他们依然是一个环。但是如果 n 是偶数,那么0号指向了2号,2号指向了4号,n-2号指向了0号,这一半元素单独构成一个环,另一半元素单独构成一个环。
    回到题目中,我们找到B中所有的环,对于B中长度为奇数的环,我们可以选择在A中用同样长度的一个环来得到它,也可以选择用一个长度为2倍的环来得到它。而对于B中长度为偶数的环,我们只能选择在A中用长度为它二倍的环来得到它,所以在B中同一长度为偶数的环,他们的个数必须是偶数个。

    char s[30];
    int T, vis[N], cnt[30];
    int main() {
        scanf("%d", &T);
        while(T--){
            scanf("%s", s);
            memset(cnt, 0, sizeof cnt);
            memset(vis, 0, sizeof vis);
            for (int i = 0; i < 26;i++){
                if(!vis[i]){
                    int j = i, n = 0;
                    do{
                        vis[j] = 1;
                        j = s[j] - 'A';
                        n++;
                    } while (j != i);
                    cnt[n]++;
                }
            }
            int flag = true;
            for (int i = 2; i <= 26;i+= 2){
                if(cnt[i] % 2 == 1)
                    flag = false;
            }
            puts(flag ? "Yes" : "No");
        }
        return 0;
    }
    

    UVA 11077 排列统计

    题意:

    给定一个长度为n的排列,可以通过一系列的交换变成{1,2,3,...n}。给定n和k,统计有多少个排列至少需要交换 k 次才能变成{1,2,...,n}。

    分析

    把这个长度为n的排列看成一个置换,我们每次交换操作肯定是在循环中选择两个数字进行交换。每次交换可以等效于将环的长度减1,也就是把某个元素从环中剔除。(可以举几个例子),所以c个元素的循环,总共需要c-1次交换操作。
    f[i][j]为长度为i的循环需要交换 j 次才能变成顺序排列的排列个数。
    (f[i][j] = f[i-1][j-1] * (i-1) + f[i-1][j])
    前面的表示将第 i 个元素随便插入到前面 i-1 个元素组成的若干个圆排列中(联系第一类斯特林数),后面的表示将第 i 个元素单独构成一个环,它并不对交换操作造成贡献

    ull f[N][N];
    
    int main() {
        memset(f, 0, sizeof f);
        f[1][0] = 1;
        for (int i = 2; i <= 21;i++){
            for (int j = 0; j < i;j++){
                f[i][j] = f[i - 1][j];
                if(j > 0)
                    f[i][j] += f[i - 1][j - 1] * (i - 1);
            }
        }
        int n, k;
        while(scanf("%d%d",&n,&k) == 2 && n)
            printf("%llu
    ", f[n][k]);
        return 0;
    }
    
  • 相关阅读:
    修改其他输入法为android 默认输入法
    {php 数据类型}
    转:PHP.ini配置文件(中文)
    php导出任意mysql数据库中的表去excel文件
    php输出、写入csv
    smarty二级分类代码和模版循环例子
    笔记:使ecshop 模板中可引用 常量
    Windows下Apache2不同域名解析不同目录解决方法
    {php 数组}
    Apache中.htaccess文件功能
  • 原文地址:https://www.cnblogs.com/1625--H/p/12333296.html
Copyright © 2011-2022 走看看