1. 程式人生 > >10601 - Cubes(Ploya)

10601 - Cubes(Ploya)

str neu while 利用 continue i++ ont title received

UVA 10601 - Cubes

題目鏈接

題意:給定正方體12條棱的顏色,要求用這些棱能組成多少不同的正方體

思路:利用ploya定理去求解,分類討論,正方體一共24種旋轉。相應的旋轉方式有4種:
1、不動
2、沿兩面中點連線旋轉
3、沿對頂點連線旋轉
4、沿兩棱中點連線旋轉

簡單推算出每種情況相應的循環組數。在加上組合數學去進行選擇顏色求解。註意第4種情況中,有兩條棱和其它的循環長度是不同的,能夠枚舉然後扣掉討論。

代碼:

#include <stdio.h>
#include <string.h>

int t, color[6], save[6], c[13][13];

long long solve(int k) {
	long long sum = 0, ans = 1;
	for (int i = 0; i < 6; i++) {
		if (save[i] % k) return 0;
		save[i] /= k;
		sum += save[i];
	}
	for (int i = 0; i < 6; i++) {
		ans *= c[sum][save[i]];
		sum -= save[i];
 	}
 	return ans;
}

long long solve1() {
	memcpy(save, color, sizeof(save));
	return solve(1);
}

long long solve2() {
	memcpy(save, color, sizeof(save));
	long long ans = 6 * solve(4);
	memcpy(save, color, sizeof(save));
	return ans + 3 * solve(2);
}

long long solve3() {
	memcpy(save, color, sizeof(save));
	return 8 * solve(3);
}

long long solve4() {
	long long ans = 0;
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 6; j++) {
  			memcpy(save, color, sizeof(save));
  			save[i]--; save[j]--;
  			if (save[i] < 0 || save[j] < 0) continue;
  			ans += 6 * solve(2);
  		}	
 	}
 	return ans;
}

int main() {
	for (int i = 0; i <= 12; i++) {
		c[i][0] = c[i][i] = 1;
		for (int j = 1; j < i; j++)
			c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
 	}
	scanf("%d", &t);
	while (t--) {
		int col;
		memset(color, 0, sizeof(color));
		for (int i = 0; i < 12; i++) {
			scanf("%d", &col);
			color[col - 1]++;
		}
		printf("%lld\n", (solve1() + solve2() + solve3() + solve4()) / 24);
	}
	return 0;
}


10601 - Cubes(Ploya)