Skip to content

USACO 2020 US Open Contest Bronze Division - Cowntact Tracing#

Problem link: here

Solution Author: Stefan Dascalescu

Problem Solution#

This problem can be solved using brute force given enough optimizations and observing that the actual number of operations done is not too big.

Source codes#

The source code in C++ can be seen below.

#include <fstream>
#include <iostream>
using namespace std;

bool cow_ends_infected[101];
int N, cowx[251], cowy[251]; 

bool consistent_with_data(int patient_zero, int K) 
{
    bool infected[101] = {false};
    int num_handshakes[101] = {0};
    infected[patient_zero] = true;
    for (int t = 0; t <= 250; t++) 
    {
        int x = cowx[t], y = cowy[t];
        if (x > 0) 
        {
            if (infected[x])
                num_handshakes[x]++;
            if (infected[y])
                num_handshakes[y]++;
            if (num_handshakes[x] <= K && infected[x])
                infected[y] = true;
            if (num_handshakes[y] <= K && infected[y])
                infected[x] = true;
        }
    }
    for (int i = 1; i <= N; i++)
        if (infected[i] != cow_ends_infected[i])
            return false;
    return true;
}

int main(void) 
{
    int T, t, x, y;
    string s;

    ifstream cin("tracing.in");
    ofstream cout("tracing.out");
    cin >> N >> T >> s;
    for (int i = 1; i <= N; i++)
        cow_ends_infected[i] = s[i - 1] == '1';
    for (int i = 0; i < T; i++) 
    {
        cin >> t >> x >> y;
        cowx[t] = x;
        cowy[t] = y;
    }

    bool possible_i[101] = {false};
    bool possible_K[252] = {false};
    for (int i = 1; i <= N; i++)
        for (int K = 0; K <= 251; K++)
            if (consistent_with_data(i, K))
            {
                possible_i[i] = true;
                possible_K[K] = true;
            }

    int lower_K = 251, upper_K = 0, num_patient_zero = 0;
    for (int K = 0; K <= 251; K++)
        if (possible_K[K])
            upper_K = K;
    for (int K = 251; K >= 0; K--)
        if (possible_K[K])
            lower_K = K;
    for (int i = 1; i <= N; i++)
        if (possible_i[i])
            num_patient_zero++;

    cout << num_patient_zero << " " << lower_K << " ";
    if (upper_K == 251)
        cout << "Infinity\n";
    else
        cout << upper_K << "\n";

    return 0;
}