LA3693
来源:互联网 发布:web前端开发必备软件 编辑:程序博客网 时间:2024/05/19 17:52
题意:在给出的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
思路:
先将数字进行排序,枚举四位数字,将所有等于temp的状态存入val[temp][i]中,然后判断i & val[temp][j]) == 0 如果是的话 就表示说他们的数字都是不一样的 就可以将st[i | val[temp][j]]的状态加1。最后讲st[i] * st[i ^ ((1 << 16) - 1)]所有的和加起来除以2就可以了,除以2是因为会出现重复的。
代码:
#include <iostream>using namespace std;#include <stdio.h>#include <cstring>#include <vector>#include <algorithm>int num[20];int count1[20];int vis[20];vector<int> val[12000];int st[1 << 17];bool judge(int x) { int cnt = 0; for(int i = 0; i < 16; i++) { if(x & (1 << i)) count1[cnt++] = num[i]; } return cnt == 4;}int main() { int T = 0; while(scanf("%d",&num[0]) && num[0]) { //memset(count1,0,sizeof(count1)); for(int i = 1; i < 16; i++) scanf("%d",&num[i]); for(int i = 0; i < 12000; i++) val[i].clear(); memset(st,0,sizeof(st)); sort(num,num + 16); for(int i = 0; i < (1 << 17); i++) { if(judge(i)) { do { int temp = count1[0] * 4 + count1[1] * 3 + count1[2] * 2 + count1[3]; for(int j = 0; j < val[temp].size(); j++) if((i & val[temp][j]) == 0) st[i|val[temp][j]]++; val[temp].push_back(i); }while(next_permutation(count1,count1 + 4)); } } long long ans = 0; for(int i = 0 ; i < (1 << 16); i++) { ans += st[i] * st[i ^ ((1 << 16) - 1)]; } printf("Case %d: %lld\n",++T,ans/2); } return 0;}
0 0