(2020牛客暑期多校训练营)[四] Investigating Legions

题目描述
在这里插入图片描述

样例
输入

1
10 20
101110101010101010100010010101010100101010010

输出

0 0 1 0 1 0 1 0 1 0

思路
将这道题转换一下,发现这是一道关于染色的题目。
但是由于给出的信息可能是错的,所以我们假设若条件的一半及以上都是正确,则这一条信息是正确的。反之,就是错误的。
我们先遍历每一个点,若被染过了,则跳过。若没有被染,搜索一下和他在一个军团的军队,并验证一下这一条信息是否正确。若正确,则将它染色。反之,跳过。每搜索完一个点,也就表示把这一个军团的人都染好了色,所以在下一次搜索前,把染的颜色更换一下即可。
代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t,n,m,a[305];
    bool b[305][305];
    char c[90005];
    for(scanf("%d",&t);t--;)
    {
        int d=0,e=0;
        scanf("%d%d%s",&n,&m,c);
        for(int i=0;i<n;i++)//转化为二维数字的形式,利于后来的判断
        {
            for(int j=i+1;j<n;j++)
                b[i][j]=b[j][i]=c[d++]-'0';
            b[i][i]=1;
        }
        memset(a,-1,sizeof(a));
        for(int i=0;i<n;i++)
            if(a[i]==-1)//没被染过色
            {
                vector<int> g(0);
                for(int j=0;j<n;j++)if(b[i][j]&&a[j]==-1)g.push_back(j);//找到和它在一个军团的军队
                for(int j=0;j<n;j++)
                {
                    int sum=0;
                    for(int k=0;k<g.size();k++)if(b[g[k]][j] && a[j]==-1)sum++;
                    if(sum>=g.size()/2)a[j]=e;//若这条信息为真,染上色
                }
                e++;//更换染的颜色
            }
        for(int i=0;i<n;i++) printf("%d ",a[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bbbll123/article/details/107496056