2 条题解

  • 0
    @ 2025-10-8 16:52:30

    //一眼 poyal ,简单构建个群

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 50;
    int a[N], n, m, b[N];
    LL ans;
    bool v[N];
    
    void calc(int tr[]) {
        memset(v, 0, sizeof(v));
        int len = 0; LL sum = 1;
        for (int i = 1; i <= n; i++) if (!v[i]) {
            int p = i; len++;  //累计轮换个数 
            while (!v[p]) {
                v[p] = 1;
                p = tr[p];
            }
        }
        for (int i = 1; i <= len; i++) sum *= m;
        ans += sum;
    }
    
    int main() {
        while (scanf("%d%d", &m, &n) != EOF) {
            if (n == 0 && m == 0) break;
            
            ans = 0; 
            for (int i = 1; i <= n; i++) a[i] = i;
            //思考后发现,一共就只有 2n种置换 
            for (int i = 1; i <= n; i++) {
                calc(a);
                
                for (int j = 1; j <= n; j++) {  //对称置换 
                    if ((n & 1) && j == n / 2 + 1) b[j] = a[j];
                    else b[j] = a[n - j + 1];
                }
                calc(b);
                
                int nn = a[n];
                for (int j = n; j >= 2; j--) a[j] = a[j - 1];  //轮换 
                a[1] = nn;
            }
            printf("%lld\n", ans / (2 * n)); 
        }
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:52:23
      //一眼 poyal ,简单构建个群 
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      const int N=50;
      int a[N], n, m, b[N];
      LL ans;
      bool v[N];
      void calc(int tr[]){
      	memset(v, 0, sizeof(v));
      	int len=0; LL sum=1;
      	for(int i=1; i<=n; i++) if(!v[i]){
      		int p=i; len++;  //累计轮换个数 
      		while(!v[p]){
      			v[p]=1;
      			p=tr[p];
      		}
      	}
      	for(int i=1; i<=len; i++) sum*=m;
      	ans+=sum;
      }
      int main(){
      	while(scanf("%d%d", &m, &n)!=EOF){
      		if(n==0 && m==0) break;
      		
      		ans=0; 
      		for(int i=1; i<=n; i++) a[i]=i;
      		//思考后发现,一共就只有 2n种置换 
      		for(int i=1; i<=n; i++){
      			calc(a);
      			
      			for(int j=1; j<=n; j++){  //对称置换 
      				if((n&1) && j==n/2+1) b[j]=a[j];
      				else b[j]=a[n-j+1];
      			}
      			calc(b);
      			
      			int nn=a[n];
      			for(int j=n; j>=2; j--) a[j]=a[j-1];  //轮换 
      			a[1]=nn;
      		}
      		printf("%lld\n", ans/(2*n)); 
      	}
      	return 0;
      }
      • 1

      *【Polya计数法】[POJ2409] Let it Bead

      信息

      ID
      592
      时间
      1000ms
      内存
      128MiB
      难度
      9
      标签
      递交数
      9
      已通过
      5
      上传者