Monday, September 11, 2006 Match summary
This problem set was a bit harder then the average High School match. Though the problems didn't require a
knowledge of complex algorithms, all of them required some careful coding, especially when handling border
cases.
These challenges led to a success rate of around 60% for each of the problems. The ProblemsXoxUsed as: Division One  Level One:
All you need to do is to loop through the text, mark all the letters that are included in a "xox" and return the number of marked letters. The sample code can be as follows: public int count(String text) { int res=0; boolean b[]=new boolean[50]; for(int i=0;i<text.length()2;i++) if(text.substring(i,i+3).equals("xox")) b[i]=b[i+1]=b[i+2]=true; for(boolean x : b)if(x)res++; return res; }It doesn't seem difficult to code, and yet many, even high rated coders, got it wrong. Most of the failed solutions weren't wrong answers, but exceptions when one reaches out of the array or string bounds, for testcases like "h". You can also look at the nice fpavetic solution that uses set, in place of array, for marking letters. FriendsTrouble Used as: Division One  Level Two:
If you are familiar with the basis of the grah theory, this problem can be translated into
TournamentSchedule Used as: Division One  Level Three:
After taking a glance at the constraints one should realize that, with a maximum of six teams, a bruteforce solution won't have a problem running in time. There are two things you need to handle when generating the schedule:
To address the first point you can assign the unique representation to every round. One way to do that is representing it as a list of n/2 pairs, where each pair has the lower index on the first position and additionally pairs are sorted by the first element. In example: A B C 35 12 04 21 35 12 04 40 35All A,B,C represent the same round, but only C is corresponding to the above constraints. Please note that every round setting can be uniquely represented in this fashion. So generating only rounds in this format will ensure that you will count each of the schedules exactly once. Now generating all the schedules can be done by recursive function, which generates pairs one by one: int generate(int round, int match){ if(round == n1){ //we have found a solution return 1; } if(match == n/2){ //the whole round was generated return(round + 1, 0); } int result = 0; int a = 0; //we set a to the first team that wasn't assigned in that round while(usedInRound[a][round])a++; usedInRound[a][round] = true; //b will be always greater than a for(int b = a+1;b<n;b++){ if(usedInRound[b][round])continue; //every two teams can play only once, one against the other. if(played[a][b])continue; usedInRound[b][round] = true; played[a][b] = true; result += generate(round, match+1); usedInRound[b][round] = false; played[a][b] = false; } usedInRound[a][round] = false; return result; }The only thing missing is compliance with the given preferences. You just need to add a check in each step, before generating the pair (a,b) in any round, to test if a or b needs to play with somebody else in that round. If it's so, you don't take this pair. The other way is to add a check, after generating the each whole round, to see if the needed matches are in it. You can take a look on the fastest solution by Weiqi, who used this approach. 
