UVALive - 3693 Balancing the Scale

题意:在给出的16个数中,求使得满足

x 1 * 4 + x 2 * 3 + x 3 * 2 + x 4 = x 5 + x 6 * 2 + x 7 * 3 + x 8 * 4
y 1 * 4 + y 2 * 3 + y 3 * 2 + y 4 = y 5 + y 6 * 2 + y 7 * 3 + y 8 * 4

这两个等式的个数有多少。

思路:状态枚举,先枚举四个数,然后查找是否有与这四个数组成的等式和的结果一样的组合,且这个组合与这四个数不相冲突,最后就是通过计算

st[i]*st[i^state]的总和就是,state表示全都有的状态

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

int a[20],num[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))
            num[cnt++] = a[i];
    }
    return cnt == 4;
}

int main(){
    int t = 0;
    while (scanf("%d",&a[0]) != EOF && a[0]){
        for (int i = 1; i < 16; i++)
            scanf("%d",&a[i]);
        for (int i = 0; i < 12000; i++)
            val[i].clear();
        memset(st,0,sizeof(st));
        sort(a,a+16);
        for (int i = 0; i < (1<<17); i++){
            if (judge(i)){
                do{
                    int temp = num[0]*4+num[1]*3+num[2]*2+num[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(num,num+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;
}



你可能感兴趣的:(UVALive - 3693 Balancing the Scale)