Codeforces 549B. Looksery Party 构造

题目链接: http://codeforces.com/problemset/problem/549/B

题意:

你现在拥有一个 n ∗ n n*n nn 01 01 01 数组 a a a ,和一个长为 n n n 的数组 b b b,现在要你选出一些行的集合 X X X,使得对于每一列 j j j 所有行的和 ∑ a [ i ] [ j ] ( i ∈ X ) \sum a[i][j] (i\in X) a[i][j](iX) 不等于 b j b_j bj

做法:

很是神奇的构造方法,对于任意一个时刻,如果没有一个 b j = 0 b_j=0 bj=0 ,那么我们就可以一个都不选,结束选择。

如果存在一个列的 b j = 0 b_j=0 bj=0 ,那么就选择这第 j j j 个人,因为他一定会给自己发信息,所以这一列 j j j 就能保证不等于 b j b_j bj

如此贪心下去就可以了,发现好像确实不会有一种情况不满足。

代码

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=105;
int mp[maxn][maxn],n;
int a[maxn],vis[maxn];
vector<int> ans;
int main(){
    scanf("%d",&n);
    rep(i,1,n)
        rep(j,1,n)
            scanf("%1d",&mp[i][j]);

    rep(i,1,n){
        scanf("%d",&a[i]);
    }
    int f=1;
    while(f){
        f=0;
        rep(i,1,n){
            if(!vis[i]&&a[i]==0){
                vis[i]=1; f=1;
                ans.push_back(i);
                rep(j,1,n){
                    if(mp[i][j]&&!vis[j]){
                        a[j]=a[j]-1;
                    }
                }
            }
        }
    }
    printf("%d\n",ans.size());
    if(ans.size()){
        sort(ans.begin(),ans.end());
        for(int i=0;i<ans.size();i++){
            printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');
        }

    }
    return 0;
}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页