CSDN 高校俱乐部: 排列搜索

CSDN 高校俱乐部/英雄会 题目;

设数组a包含n个元素恰好是0..n - 1的一个排列,给定b[0],b[1],b[2],b[3]问有多少个0..n-1的排列a,满足(a[a[b[0]]]*b[0]+a[a[b[1]]]*b[1]+a[a[b[2]]]*b[2]+a[a[b[3]]]*b[3])%n==k ?

 

输入包含5个参数:N,K,B0,B1,B2,B3,其中 4<= N<12, 0 <= K,B0,B1,B2,B3 < N

 

单全排列超时代码:

#include <stdio.h>

#include <string.h>

int b[5];

int c[5];

int a[15];

int aa[15];

int vis[15];

int n, sum, k;



int B_same_num(int b[]){

	int i, j;

	int p = 4;

	for(i=0;i<3;++i){

		if(b[i] == -1) continue;

		for(j=i+1;j<4;++j)

			if(b[i] == b[j]){

				b[j] = -1;

				--p;

			}

	}

	return p;

}



void reset(int b[]){

	int i, j;

	for(i=j=0; j < 4; ++j){

		if(b[j] != -1)

			c[i++] = b[j];

	}

}



void dfs(int s, int num) {

    int i;

    if(s == n) {

        if(4 == num)

        	if( (c[0]*a[a[0]] + c[1]*a[a[1]] + c[2]*a[a[2]] + c[3]*a[a[3]])%n == k )

        		++sum;

        if(3 == num)

        	if( (c[0]*a[0] + c[1]*a[1] + 2 * c[2]*a[2])%n == k )

        		++sum;

        if(2 == num)

        	if( (c[0]*a[0] + 3 * c[1]*a[1])%n == k )

        		++sum;

        if(1 == num)

        	if( (4 * c[0]*a[0])%n == k )

        		++sum;





        return;

    }

    for(i = 0; i < n; i++) {

        if(vis[i]) continue;

        vis[i] = 1;   

        a[s] = i;  

        dfs(s+1, num);      

        vis[i] = 0;   

    }

}



int main(int argc, char const *argv[])

{

	int t, i;

	scanf("%d", &t);

	while(t--){

		sum = 0;

		scanf("%d %d", &n, &k);

		for(i=0;i<4;++i)

			scanf("%d", &b[i]);

		int num = B_same_num(b);

		reset(b);

		dfs(0, num);

		printf("%d\n", sum);

	}

	return 0;

}

  

 

 

 

双全排列改进后AC的代码:

#include <stdio.h>

#include <string.h>

int b[5];

int c[5];

int a[15];

int d[15];

int sui[15];

int vis[15];

int vis1[15];

int arr[15];

int jiecheng[20];

int n, sum, k;



void _jiecheng(){

    jiecheng[0] =1;

    jiecheng[1] =1; 

    jiecheng[2] =2;

    jiecheng[3] =6; 

    jiecheng[4] =24; 

    jiecheng[5] =120; 

    jiecheng[6] =720;

    jiecheng[7] =5040;

    jiecheng[8] =40320;

    jiecheng[9] =362880;

    jiecheng[10] =3628800;

    jiecheng[11] =39916800;

    jiecheng[12] =479001600;

}



void init(){

    int i;

    for(i=0;i<15;++i) arr[i] = 0;

}



int B_same_num(int b[]){

	int i, j;

	int p = 4;

	for(i=0;i<3;++i){

		if(b[i] == -1) continue;

		for(j=i+1;j<4;++j)

			if(b[i] == b[j]){

				b[j] = -1;

				--p;

			}

	}

	return p;

}



void reset(int b[]){

	int i, j;

	for(i=j=0; j < 4; ++j){

		if(b[j] != -1)

			c[i++] = b[j];

	}

}



void suiji(int s, int num, int b_num) {

    int i, j;

    int dd;

    dd = n - num - b_num;



    if(s == num) {

        j=0;

        for(i = 0; i < b_num; i++){

            if(arr[a[c[i]]] == 1) continue;

            else {

                a[a[c[i]]] = sui[j++];

            }

        }

        if(4 == b_num){

            if( (c[0]*a[a[c[0]]] + c[1]*a[a[c[1]]] + c[2]*a[a[c[2]]] + c[3]*a[a[c[3]]])%n == k ){

                sum+=jiecheng[dd];

            }

        }

        if(3 == b_num)

            if( (c[0]*a[a[c[0]]] + c[1]*a[a[c[1]]] + 2 * c[2]*a[a[c[2]]])%n == k )

                sum+=jiecheng[dd];

        if(2 == b_num)

            if( (c[0]*a[a[c[0]]] + 3 * c[1]*a[a[c[1]]])%n == k )

                sum+=jiecheng[dd];

        if(1 == b_num)

            if( (4 * c[0]*a[a[c[0]]])%n == k )

               sum+=jiecheng[dd];

        return;

    }

    for(i = 0; i < n; i++) {

        if(vis1[i]) continue;

        if(vis[i]) continue;

        vis1[i] = 1;   

        sui[s] = i;     

        // printf("sui : %d\n", sui[s]);

        suiji(s+1, num, b_num);      

        vis1[i] = 0;   

    }

}



int arr_num(int num){

    int dd = 0;

    int i;

    for(i=0;i<num;++i)

        if(arr[a[c[i]]] == 1) continue;

        else ++dd;

    return dd;

}





void dfs(int s, int num) {

    int i, t;

    if(s == num) {

        init();

        for(i=0;i<num;++i){

            a[c[i]] = d[i];

            arr[c[i]] = 1;

        }

        t = arr_num(num);

        suiji(0, t, num);

        return;

    }

    for(i = 0; i < n; i++) {

        if(vis[i]) continue;

        vis[i] = 1;   

        d[s] = i;  

        dfs(s+1, num);      

        vis[i] = 0;   

    }

}



int main(int argc, char const *argv[])

{

	int t, i;

	scanf("%d", &t);

	while(t--){

		sum = 0;

        _jiecheng();

		scanf("%d %d", &n, &k);

		for(i=0;i<4;++i)

			scanf("%d", &b[i]);

		int num = B_same_num(b);

		reset(b);

		dfs(0, num);

		printf("%d\n", sum);

	}

	return 0;

}

  

 

精简版 代码:

#include <stdio.h>

#include <string.h>



int a[12];

int b[4];

int N, K, ans;

int v[12];

int fac[14];



void factorial(){

	int i;

    fac[0] = 1;

	for(i=1;i<=12;++i) 

		fac[i] = fac[i-1]*i;

}



void dfs2(int s){

	int t;

	if(s == 4){

		if ((a[a[b[0]]]*b[0]+a[a[b[1]]]*b[1]+a[a[b[2]]]*b[2]+a[a[b[3]]]*b[3])%N==K){

			t = 0;

			int i;

			for(i=0;i<N;++i)

				if(a[i] == -1) ++t;

			ans += fac[t];

		}

		return;

	}

    if(a[a[b[s]]] != -1)

    	dfs2(s+1);

    else{

    	int i;

    	for(i=0;i<N;++i)

    		if(!v[i]){

    			v[i] = 1;

    			a[a[b[s]]] = i;

    			dfs2(s+1);

    			v[i] = 0;

    			a[a[b[s]]] = -1;

    		}

    }

}



void dfs(int s){

	int i;

	if(s == 4){

		dfs2(0);

		return;

	}

	if(a[b[s]] != -1)

		dfs(s+1);

	else{

		for(i=0;i<N;++i)

			if(!v[i]){

				v[i] = 1;

				a[b[s]] = i;

				dfs(s+1);

				v[i] = 0;

				a[b[s]] = -1;

			}

	}

}



int main(int argc, char const *argv[])

{

	int i;

	scanf("%d%d%d%d%d%d", &N, &K, &b[0], &b[1], &b[2], &b[3]);

	ans = 0;

	memset(v, 0, sizeof(v));

	for(i=0;i<12;++i) a[i] = -1;

	factorial();

	dfs(0);

	printf("%d\n", ans);

	return 0;

}

  

  

测试数据 :

 

#include <stdio.h>

#include <string.h>



int howmany (int N,int K,int B0,int B1,int B2,int B3)

{

   if(N==4 && K==0 && B0==3 && B1==2 &&B2==1 &&B3==0) return 4;

   if(N==5 && K==2 && B0==1 && B1==2 &&B2==3 &&B3==4) return 40;

   if(N==6 && K==4 && B0==5 && B1==4 &&B2==3 &&B3==2) return 78;

   if(N==7 && K==6 && B0==6 && B1==4 &&B2==2 &&B3==0) return 684;

   if(N==8 && K==1 && B0==0 && B1==1 &&B2==2 &&B3==3) return 5454;

   if(N==9 && K==3 && B0==4 && B1==8 &&B2==1 &&B3==2) return 44028;

   if(N==10 && K==5 && B0==3 && B1==7 &&B2==9 &&B3==0) return 349776;

   if(N==11 && K==7 && B0==3 && B1==1 &&B2==8 &&B3==9) return 3651984;

   if(N==11 && K==0 && B0==0 && B1==0 &&B2==0 &&B3==0) return 39916800;

   if(N==11 && K==5 && B0==4 && B1==3 &&B2==2 &&B3==1) return 3662976;

   return 0;

}

  

 

 

 

PS :  和别人的代码根本无法媲美。。以后在重新改进一下这份代码!

 

 

你可能感兴趣的:(csdn)