題目連結: https://zerojudge.tw/ShowProblem?problemid=c460

# 內容

亞歷山大將軍準備派遣一支精銳部隊前往攻打鄰國,他麾下有三個種族;每個種族各有不同兵種。
為了平衡部隊的組成份子,亞歷山大會從三個種族各選擇一個兵種。此外,他還會考慮這個部隊是否能涵蓋「對空攻擊」、「範圍攻擊」和「遠距攻擊」三種特性。舉例來說,亞歷山大將軍麾下的三個種族各有三個兵種如下:

亞歷山大可以選擇法師、骷髏兵團和勇士這個組合,因為這個組合涵蓋了三個種族和三個特性;但他不能選擇弓箭手、骷髏兵團和投矛手這個組合,因為這個組合未能涵蓋「範圍攻擊」這個特性;他也不能選擇弓箭手、炸彈兵和炸彈塔這個組合,因為這個組合未能涵蓋「哥布林」這個種族。
亞歷山大為了向國王解釋,他想要告訴國王總共有多少種可能的組合,請你幫幫他。

# 解題思路

可以記錄每種排列組合的數量。每種排列組合可以用 2 進位觀點,ai 權值 4、ri 權值 2、di 權值 1,將 3 種特性表示成 1 個特性值。
對 3 種族的特性值窮舉,如果 3 個特性值位元運算為 7,數量相乘
-> 此作法稱作為位元壓縮喔~~

# 程式碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int army[4][8];
int main(){
    int n;
    while(cin>>n){
        memset(army,0,sizeof(army));
        for(int i=0,type,ai,ri,di;i<n;i++){
            cin>>type>>ai>>ri>>di;
            army[type][ai*4+ri*2+di]++;
        }
        ll ans = 0;
        for(int i=0;i<8;i++)
            for(int j=0;j<8;j++)
                for(int k=0;k<8;k++)
                    if((i|j|k)==7)
                        ans+=army[1][i]*army[2][j]*army[3][k];
        cout<<ans<<endl;
    }
}
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay