简体   繁体   中英

CS50 Tideman lock_pairs skips final pair if it creates cycle & everything works as meant to

I have a recursive function which checks whether the loser of a pair has previously won, if this repeats enough times to the point where the most recent loser is the initial winner that I was checking for, then a cycle occurs and I omit the winner.

I also set the winner which I am omitting to a negative number so I can reuse the algorithm and future links can be made (ie it will know that the winner was omitted)

pairs is an array containing winners and losers

locked[i][j] is a boolean array which is true if i wins over j

I have checked this by manually creating my own pairs array and the last pair still changes to True even when a cycle has been created previously. Yet I still get the error with check50 lock_pairs skips final pair if it creates cycle:

lock_pairs did not correctly lock all non-cyclical pairs
typedef struct
{
    int winner;
    int loser;
}
pair;

// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{
    for (int i = 0; i < pair_count; i++)
    {
        global_status = false; 
        check(i, i);

            if (global_status == true)
            {
                locked[pairs[i].winner][pairs[i].loser] = false;
            }
            else
            {
                locked[pairs[i].winner][pairs[i].loser] = true;
            }
    }
    return;
}

void check(int current_winner, int i)   
{
    if (global_status == false)
    {
        for (int j = 0; j <= i; j++)
        {
            if (pairs[current_winner].loser == pairs[j].winner)
            {
                if (j == i) // if j = i then the current winner in locked_pairs creates a cycle
                {
                    global_status = true;
                    pairs[i].winner = -1; // where i is the initial winner in lock_pairs
                }
                return check(j, i); 
            }
        }
    }
}

First with check50 make sure you get correct every previous step, if so...

My suggestion - with pseudo code - is that you try a different approach in your check function, one that does the following before locking a pair - for instance pair x -:

1.- Look if x.loser has won any locked pair.

1.a.- If false you can lock the pair

1.b.- If true, run again given function, but the loser now is the one who lost against x.loser

1.bi- If true don't lock.

1.b.ii.- If false lock.*

The reason is that you need to detect a chain (at least two) not a complete cycle (for a complete cycle is only possible to check at the end, but that way you dont detect cycles at the middle).

*EDIT 1: Before locking, you need to asume that x.loser may win more than once, so you need to look for ALL possible chains applicable to x.loser, in case first chain didnt exist...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM