zoukankan      html  css  js  c++  java
  • 【ybt金牌导航8-5-2】彩色项链2

    彩色项链2

    题目链接:ybt金牌导航8-5-2

    题目大意

    m 个颜色的珠子,可以放 n 个组成项链,问你能做出多少个不重复的。
    重复是当项链可以通过旋转和沿中轴线翻转可以完全相同。

    思路

    这道题跟——>这一道题<——差不多。

    因为它 (n,m) 可能不一样,你会发现你之前用的化公式的方法就不能直接用上去。
    但是它范围很小,那我们就暴力搞,那这个也不是问题。

    但是它还有沿中轴线翻转的操作。
    那我们也往 Polya 定理的方向上考虑。
    那你遇到这种中间翻转的(比如回文串),就想到了奇偶分类。

    如果长度是奇数,那就一定中轴线一定要碰到一个点(也只能碰到一个),那就有 ((n-1)/2) 个两个点的循环 (1) 个一个点的循环,那就是 ((n+1)/2) 个循环。然后每个点都可以作为被中轴线碰到的点,那就一共有 (n) 个这样的置换。

    如果长度是偶数,那你会想到可以分两种可能:中轴线什么都碰不到,中轴线碰到了两个点。
    那两个都各有 (n/2) 个这样的置换,什么都碰不到的循环有 (n/2) 个,碰到两个的循环有 (2+(n-2)/2=(n+2)/2) 个。

    那按着这么算就好了。
    (记得总的置换个数有 (2 imes n) 个)

    代码

    #include<cstdio>
    #define ll long long
    
    using namespace std;
    
    int n, m;
    ll ans;
    
    void csh() {
    	ans = 0;
    }
    
    ll gcd(ll x, ll y) {//求gcd
    	if (!y) return x;
    	return gcd(y, x % y);
    }
    
    ll ksm(ll x, ll y) {//快速幂
    	ll re = 1;
    	while (y) {
    		if (y & 1) re = re * x;
    		x = x * x;
    		y >>= 1;
    	}
    	return re;
    }
    
    int main() {
    	scanf("%d %d", &m, &n);
    	while (m || n) {
    		csh();
    		
    		for (int i = 1; i <= n; i++) {
    			ans += ksm(m, gcd(i, n));//旋转
    		}
    		if (n & 1) ans += n * ksm(m, (n + 1) / 2);//沿中轴线翻转(分奇偶讨论)
    			else ans += n / 2 * ksm(m, n / 2) + n / 2 * ksm(m, (n + 2) / 2);
    		
    		ans /= n * 2;
    		
    		printf("%lld
    ", ans);
    		
    		scanf("%d %d", &m, &n);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    C语言面试题——大小端测试(一)
    C语言面试题——联合体测cpu的大小端
    C语言面试题——sizeof的注意点
    C语言面试题——联合体测cpu的大小端
    C语言面试题——指针运算
    poj2183
    poj1972
    poj2014
    poj1970
    poj1918
  • 原文地址:https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-5-2.html
Copyright © 2011-2022 走看看