计蒜客 Automatic Control Machine(二进制枚举+bitset)

传送门

题意:给定一个c列r行的矩阵,问最少选出多少行元素才能保证每一列至少一个1,对于数据范围,可以进行二进制枚举,其实突然想起来这个题目就是为了练习顺便学习一下二进制枚举,还可以练习一下bitset的使用。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef long long LL;
const int maxn = 2e4 + 10;
const int maxm = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 11092019;
int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
bitset<510> a[20];
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    IO;
    int T, r, c;
    cin >> T;
    while (T--)
    {
        cin >> c >> r;
        char ch;
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
            {
                cin >> ch;
                if (ch == '1')
                    a[i][j] = 1;
                else
                    a[i][j] = 0;
            }
        int ans = inf;
        for (int k = 0; k < (1 << r); k++) // 枚举所有子集
        {
            bitset<510> t;
            int cnt = 0;
            for (int i = 0; i < r; i++)
            {
                if (k & (1 << i))
                    t |= a[i], cnt++;
            }
            bool flag = 1;
            for (int i = 0; i < c; i++)
                if (t[i] == 0)
                {
                    flag = 0;
                    break;
                }
            if (flag == 1)
                ans = min(ans, cnt);
        }
        if (ans == inf)
            cout << -1 << endl;
        else
            cout << ans << endl;
    }
    return 0;
}

 

你可能感兴趣的:(搜索,暴力)