标签:
题目大意:给出一个式子,和16个数字,问符合以下两个式子的情况有多少种
x1* 4 + x2* 3 + x3* 2 + x4 = x5 + x6* 2 + x7* 3 + x8* 4
y1* 4 + y2* 3 + y3* 2 + y4 = y5 + y6* 2 + y7* 3 + y8* 4
解题思路:枚举4个数字的全排列,然后找一下是否有其他4个数字的全排列的其中一种状况和当前这个情况相同,如果相同的话就加入.
要注意其他四个数字不能和当前这四个数字有交集
这样的话,就可以得到符合其中一个式子的情况的总数了(8位)
最后只需要统计一下cnt[i] * cnt[i ^ ((1 << 16) - 1)]的所有情况,再除以2,就是答案了
今晚被坑了:一直搞不懂为什么要排序。。。因为next_permutation的要实现全排列的话就要从小到大排
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = (1 << 16);
const int M = 12000;
vector<int> sta[M];
int x[16], num[16], cnt[N];
void init() {
for(int i = 1; i < 16; i++)
scanf("%d", &num[i]);
sort(num, num + 16);
for(int i = 0; i < M; i++)
sta[i].clear();
memset(cnt, 0, sizeof(cnt));
}
bool judge(int s) {
int count = 0;
for(int i = 0; i < 16; i++)
if(s & (1 << i))
x[count++] = num[i];
return count == 4;
}
long long solve() {
long long ans = 0;
for(int i = 0; i < N; i++)
if(judge(i)) {
do{
int t = 4 * x[0] + 3 * x[1] + 2 * x[2] + x[3];
for(int j = 0; j < sta[t].size(); j++)
if((i & sta[t][j]) == 0)
cnt[i | sta[t][j]]++;
sta[t].push_back(i);
}while(next_permutation(x, x + 4));
}
for(int i = 0; i < N; i++)
ans += cnt[i] * cnt[i ^ (N - 1)];
return ans / 2;
}
int main() {
int cas = 1;
while(scanf("%d", &num[0]) != EOF && num[0]) {
init();
printf("Case %d: %lld\n", cas++, solve());
}
return 0;
}
UVALive - 3693 Balancing the Scale 枚举 + 状态压缩
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/46509135