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
原创粉丝点击