Investigating Legions

链接:https://ac.nowcoder.com/acm/contest/5669/I
来源:牛客网

ZYB likes to read detective novels and detective cartoons. One day he is immersed in such story:

As a spy of country B, you have been lurking in country A for many years. There are n n n troops and m m m legions in country A, and each troop belongs to only one legion. Your task is to investigate which legion each troop belongs to.

One day, you intercept a top secret message–a paper which records all the pairwise relationship between troops. You can learn from the paper that whether troop i {i} i and troop j {j} j belongs to the same legion for each ( i , j ) {(i,j)} (i,j). However, each piece of data has a independent probability of 1 S \frac{1}{S} S1 being reversed.
Formally, the troop is numbered from 0 {0} 0 to n − 1 {n-1} n1, and the region is numbered from 0 {0} 0 to m − 1 {m-1} m1. You are given n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1) boolean numbers, indicating whether i {i} i and j {j} j belong to the same region ( 1 1 1 for yes and 0 0 0 for no). However, every number will be reversed(i.e., 0 0 0 to 1 1 1 and 1 1 1 to 0 0 0) in a probablity of 1 S \frac{1}{S} S1. You can assume that the data is generated like this:
Investigating Legions_第1张图片
b e [ i ] be[i] be[i] means the region that troop i {i} i belongs to. r a n d ( ) rand() rand() can be considered as a uniform random function. i.e., select a integer from interval [ 0 , l c m ( m , S ) − 1 ] [0, \mathrm{lcm}(m, S)-1] [0,lcm(m,S)1] with equal probability.

Note that you have already known n {n} n and S {S} S, but you don’t know the exact value of m m m. Please help country B construct the original data.
输入描述:
The input contains multiple cases. The first line of the input contains a single integer T   ( 1 ≤ T ≤ 100 ) T\ (1 \le T \le 100) T (1T100), the number of cases.

For each case, the first line of the input contains two integers n , S {n,S} n,S ( 30 ≤ n ≤ 300 , 20 ≤ S ≤ 100 30 \le n \le 300,20 \le S \le 100 30n300,20S100), denoting the number of troops and the integer parameter to generate data. There is a binary string (i.e. the string only contains ‘0’ and ‘1’) with length n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1) in the next line, decribing the pairwise relationship. It is arrayed like this: ( 0 , 1 ) , ( 0 , 2 ) . . . ( 0 , n − 1 ) , ( 1 , 2 ) … ( n − 3 , n − 1 ) , ( n − 2 , n − 1 ) (0,1),(0,2)...(0,n-1),(1,2) \dots (n-3,n-1),(n-2,n-1) (0,1),(0,2)...(0,n1),(1,2)(n3,n1),(n2,n1).

m {m} m is not given but it is guaranteed that 1 ≤ m ≤ ⌊ n 30 ⌋ 1 \le m \le \lfloor \frac{n}{30} \rfloor 1m30n. And the sum of n {n} n over T {T} T cases doesn’t exceed 1200 {1200} 1200.
输出描述:
For each case, output integers seperated by space, the i i i-th integer describes b e [ i ] be[i] be[i]. The value of b e [ i ] be[i] be[i] is meaningless, so please output the solution with the smallest lexicographical order. For example, if there are 4 4 4 troops and 2 2 2 regions { 0 , 3 } , { 1 , 2 } {\{0,3\},\{1,2\}} {0,3},{1,2}, you should output 0   1   1   0 0 \ 1 \ 1 \ 0 0 1 1 0.
示例1

输入
1
10 20
101110101010101010100010010101010100101010010
输出
0 0 1 0 1 0 1 0 1 0

备注:
The sample input does not follow the input format, and it won’t appear in the final test. The parameter is n = 10 , m = 2 , S = 20 {n=10,m=2,S=20} n=10,m=2,S=20.
每次选择一个未被编号的点 i i i找出所有与 i i i相连且未被编号的点,遍历所有点。对于当前遍历到的点 j j j,如果 j j j看未被标记,则统计与 i i i直接相连的点中有多少与 j j j相连。显然相连的点数越多越能说明 i i i j j j属于同一类。由于未知变量太多,不能严格证明,只能通过玄学调出判定的边界。

#include 

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scanf("%c",&a)
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector
#define pii pair
#define mii unordered_map
#define msi unordered_map
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 305;
bool g[N][N];
int a[N], n, s, T;
char c;
vi tmp;

int main() {
    T = qr();
    while (T--) {
        n = qr(), s = qr();
        memset(a, -1, sizeof(a));
        repi(i, 1, n - 1) {
            repi(j, i + 1, n)sc(c), g[i][j] = g[j][i] = c - '0';
            g[i][i] = true;
        }
        int id = 0;
        repi(i, 1, n)if (a[i] == -1) {
                tmp.clear();
                repi(j, 1, n)if (g[i][j] && a[j] == -1)tmp.pb(j);
                repi(j, 1, n)
                    if (a[j] == -1) {
                        int cnt = 0;
                        for (auto k:tmp)if (g[j][k])cnt++;
                        if (cnt > tmp.size() / 2)a[j] = id;
                    }
                id++;
            }
        repi(i, 1, n)printf("%d%c", a[i], ce(i, n));
    }
    return 0;
}

你可能感兴趣的:(ACM,思维,玄学)