One Point Solution

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Saturday, 10 August 2013

ThreeColorability (SRM 587 div1 hard)

Posted on 16:03 by Unknown

(main editorial preview post)

Intro

Link to problem statement. In short, we have a square grid. We want to color the corners of the squares using at most 3 colors, in such a way that points connected by a line segment don't share a color. Is it possible? Of course is possible! so, how about making it harder? You also need to add exactly one diagonal in each of the squares. Some squares already start with diagonals. Find a way to fill the remaining diagonals.

This explanation takes the explanation for the division 2 versionas a base. In that explanation we have found a property that is both necessary and sufficient for the setup to be valid. Each row must be equal or completely opposite to the first row. The question is how to use this property to generate the lexicographically-first way to fill the remaining cells?

Is it possible?

Given a grid of some set cells and some unknowns, can the unknown cells be filled in a way that the points are 3-colorable? In a way such that the number of Zs in each 2x2 sub-rectangle is even? In a way such that each row is equal or completely opposite to the first row?

Binary grids that follow those properties follow many other properties. There is a useful one that can be derived from the row property. If each row is equal to the first row or a negative, then we can "negate" the negative rows, the result will look like this (If we once again use 1 for Z and 0 for N):


0110001100101001
0110001100101001
0110001100101001
0110001100101001
0110001100101001
0110001100101001

Then we can negate all the columns that contain 1, and the result is full of zeros. We can conclude that valid setups are those in which you negate a set of rows and a set of columns. Let us assign values to the rows and columns, 0 for rows/columns that are not negated and 1 for the negated ones. Now take a look to the following setup:


????1??????
?0??????0??
????1??????
?0?????????

If cell `(x,y)` has value 0, then there are two possibilities: a) Neither column `x` or row `y` were negated. b) Both column `x` and row `y` were negated. We can just say that the values for row `y` and column `x` must be equal. Likewise, if cell `(x,y)` had a 1, it would mean that the values for the respective row and column must be different. If the cell was '?', then there is no condition that connects the row and column directly.

Consider a set of variables such that each could be 0 or 1. There are some conditions of the form `(v_i = v_j)`, and others in the form `(v_i != v_j)`. Is there at least one way to assign valid values to the variables? If you assign 0 to a variable, the rules will force you to assign 0 to some variables and 1 to others. You can then process the rules for each of these new variables and you will be forced to assign other values to other variables. Repeat until there is a contradiction or until all variables get an assigned value. If we assigned 1 to the first variable it wouldn't really change the result, all variables would just be negated. In other words, each condition connects two variables and we just need a Depth-first search (DFS) between the variables.

Lexicographically first

Once we can confirm if a setup can be filled correctly. We can use the same function to find the lexicographically-first result. Try the first of the unknown cells in row-major order, if adding a N to this cell position is possible, then the lexicographically-first setup will have a N in this location (Because 'N' is smaller than 'Z'). If it is not possible to put a N, put a Z. Then try the remaining unknown cells in row-major order, always placing the smallest possible value in each of them.

Code


int N;
int graph[110][110];
int color[110];


void dfs(int x, int c){
if (color[x] != -1) {
return;
}
color[x] = c;
for (int i = 0; i < N ; i++) {
if (graph[x][i] != -1) {
dfs(i, (c ^ graph[x][i]));
}
}
}

bool check() {
fill(color, color+N, -1);
// do a DFS, to fill the values for the variables, start each connected
// component with 0:
for (int i = 0; i < N ; i++) {
if (color[i] == -1) {
dfs(i, 0);
}
}
for (int i = 0; i < N ; i++) {
for (int j = 0; j < N ; j++) {
// Check if there is any inconsistency:
if (graph[i][j] != -1 && ((color[i] ^ color[j]) != graph[i][j]) ) {
return false;
}
}
}

return true;
}

vector <string> lexSmallest(vector <string> cells){
int X=cells.size(), Y=cells[0].length();

N = X + Y;
for (int i = 0; i < X ; i++) {
for (int j = 0; j < Y ; j++) {
graph[i][j] = -1; //-1 means there is no connection between the variables
}
}
// For each cell != '?':
for (int i = 0; i < X ; i++) {
for (int j = 0; j < Y ; j++) {
if (cells[i][j] != '?') {
// If the cell is 'Z', the row and column must be different
// save 1 in the graph. Else 0, they must be equal.
graph[i][X+j] = graph[X+j][i] = (cells[i][j] == 'Z');
}
}
}

if (!check() ) {
// the board is already invalid
return {};
}

// Lexicographically-first.
// For each cell in row-major order:
for (int i = 0; i < X; i++) {
for (int j = 0; j < Y ; j++) {
if(cells[i][j] == '?') {
//Try with N:
graph[i][X+j] = graph[X+j][i] = 0;
if (!check()) {
// Not possible, put a Z:
graph[i][X+j] = graph[X+j][i] = 1;
}
}
}
}
// translate the result back to N/Z:
vector <string> ans(X);
for (int i = 0; i < X ; i++) {
for (int j = 0; j < Y ; j++) {
ans[i] += ((graph[i][X+j] == 0) ? 'N' : 'Z');
}
}
return ans;
}
Email ThisBlogThis!Share to XShare to Facebook
Posted in editorial.srm, topcoder | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • TopCoder SRM 557 - finally
    SRM 557 Explanation for division 1 Easy and match recap. Explanations for div2 easy and div2 medium. It feels like it has been ages since t...
  • SRM 589 Editorial
    I have finished writing the editorial for TopCoder SRM 589: http://apps.topcoder.com/wiki/display/tc/SRM+589 . As you most likely noticed. L...
  • SRM 590 recap and editorial
    Another week another Topcoder match. Not a great day. I had a bad flu and still do. Div1 500: The one with Xor Given a list of cards with nu...
  • SRM 546: relief
    I figured I should post something about this SRM. I've been very busy these weeks because the semester is ending and I tried to win a t-...
  • SRM 526: The killing wait for results
    While I wait for results, here is my perspective on this algorithm contest. It began with issues, it had to be postponed 15 minutes. TC has ...
  • SRM 554 div1 hard: TheBrickTowerHardDivOne
    Link to problem statement We got infinitely many bricks of dimensions 1x1x1 and C different colors. Count the number of towers of size 2x2...
  • SRM 533: Div1 500 MagicBoard explanation
    Finally solved it. It is a nice problem that is worth explaining in a post. You have a grid/board of at most 50x50 cells. Some cells contain...
  • Member SRM 505: Part 1
    So, let me explain a couple of problems from a Topcoder Member SRM that I wrote and never got an editorial. BTW, it was the last member SRM....
  • ListedLinks 2012-02-10
    Saturday Morning Breakfast Cereal comics: Grace Hopper's ghost That Oracle engineer blog post Oracle would really not like anyone to se...
  • Codeforces "Good bye 2013" round
    So it was a special round for coders of both divisions, problems ranged from the super easy problem A to the super difficult problems E,F,G....

Categories

  • acm
  • algorithm
  • answers
  • arenaplugin
  • badday
  • behindthescenes
  • bugs
  • c++
  • censorship
  • codechef
  • codeforces
  • contests
  • crocchamp
  • editorial
  • editorial.srm
  • embarrassing
  • explanation
  • gcj2013
  • gmp
  • goodday
  • google
  • googlecodejam
  • greed
  • groklaw
  • health
  • html
  • httpseverywhere
  • implementation
  • ipsc
  • ispc
  • java
  • kawigiedit
  • kindagoodday
  • lamebook
  • languages
  • lego
  • listedlinks
  • marathon
  • nasa
  • offtopic
  • ouch
  • postmortem
  • postportem
  • practical
  • probably_not_a_good_tip
  • problemsetting
  • programming
  • python
  • quora
  • rant
  • recap
  • slightlygoodday
  • snippet
  • srm
  • stl
  • strategy
  • swerc
  • tco
  • tco12
  • tco13
  • tco2012
  • tco2013
  • ternarysearch
  • topcoder
  • tricks
  • ubuntu
  • uva
  • vjass
  • vkcup
  • wc3
  • zinc

Blog Archive

  • ►  2014 (1)
    • ►  January (1)
  • ▼  2013 (141)
    • ►  December (14)
    • ►  November (8)
    • ►  October (13)
    • ►  September (11)
    • ▼  August (14)
      • Regarding c++ vs. python (in algorithm contests)
      • SRM 589 Editorial
      • SRM 589: Read the statement! (upd)
      • Codeforces #196: slowness
      • SRM 588: ouch (Update)
      • Editorial for SRM 587 is out
      • Test SRM#2 : In which I abuse lambdas
      • ThreeColorabilityEasy (SRM 587 div2 hard)
      • ThreeColorability (SRM 587 div1 hard)
      • SRM 587 editorial previews
      • Test SRM #2 : Revenge of the C++11
      • KawigiEdit 2.3.0
      • SRM 586 Editorial finally there
      • SRM 586 div1 easy and hard editorials
    • ►  July (15)
    • ►  June (13)
    • ►  May (13)
    • ►  April (12)
    • ►  March (11)
    • ►  February (11)
    • ►  January (6)
  • ►  2012 (94)
    • ►  December (5)
    • ►  October (6)
    • ►  September (8)
    • ►  August (6)
    • ►  July (3)
    • ►  June (5)
    • ►  May (8)
    • ►  April (10)
    • ►  March (20)
    • ►  February (16)
    • ►  January (7)
  • ►  2011 (51)
    • ►  December (7)
    • ►  November (12)
    • ►  October (5)
    • ►  September (1)
    • ►  August (3)
    • ►  July (4)
    • ►  June (3)
    • ►  May (7)
    • ►  April (3)
    • ►  March (2)
    • ►  February (1)
    • ►  January (3)
  • ►  2010 (9)
    • ►  December (4)
    • ►  October (1)
    • ►  June (1)
    • ►  May (1)
    • ►  January (2)
  • ►  2009 (1)
    • ►  December (1)
Powered by Blogger.

About Me

Unknown
View my complete profile