Cod sursa(job #178727)

Utilizator radupoenaruPoenaru Radu Constantin radupoenaru Data 14 aprilie 2008 22:51:20
Problema Litere Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
//#include <iostream.h>
#include <fstream.h>

#define false 0
#define true 1

//typedef char bool;

ifstream fcin("sudoku.in");
ofstream fcout("sudoku.out");

void prints(int s[9][9]) {
  for (int i=0; i<9; i++) {
    for (int j=0; j<8; j++)
      fcout << s[i][j] << " ";
    fcout << s[i][8] << "\n";
  }
}

void fillin(bool a[9][9][10], int s[9][9], int i, int j, int entry) {
  // adaug entry si ajustez pe a eliminand posibilitatile lui entry
  // pt aceasi linie, coloana sau bloc de 3x3.
  s[i][j] = entry;
  int k, l;
  for (k=0; k<9; k++) {
    a[i][k][entry] = (j==k);
    a[k][j][entry] = (i==k);
  }

  for (k=i-i%3; k<i+3-i%3; k++)
    for (l=j-j%3; l<j+3-j%3; l++)
      a[k][l][entry] = (k==i && l==j);
  for (int v=1; v<=9; v++)
    a[i][j][v] = (v==entry);
} 
  
bool solve(bool a[9][9][10], int s[9][9]) {
  bool done = false;

  // caut o casuta goala cu numar minim de posibilitati
  int m = 10;
  int besti, bestj;
  for (int i=0; i<9; i++) {
    for (int j=0; j<9; j++) {
      if (!s[i][j]) { // consider blanks only
	int x = 0;
	for (int v=1; v<=9; v++)
	  if (a[i][j][v]) x++;
	if (x<m) {
	  m = x;
	  besti = i;
	  bestj = j;
	}
      }
    }
  }
  if (m==10) { // nu mai sunt casute goale; afisez solutia
    prints(s);
    done = true;
  } else { // incerc diferite valori pt locatia cea mai buna
    for (int v=1; v<=9; v++) {
      if (!done && a[besti][bestj][v]) {
	// fac copii, completez o valoare si incerc sa rezolv
	bool aTry[9][9][10];
	int sTry[9][9];
	for (int i=0; i<9; i++) {
	  for (int j=0; j<9; j++) {
	    sTry[i][j] = s[i][j];
	    for (int k=1; k<=9; k++)
	      aTry[i][j][k] = a[i][j][k];
	  }
	}
	fillin(aTry,sTry,besti,bestj,v);
	done = solve(aTry,sTry);
      }
    }
  }
  return done;
} 
      
int main(void) {
  int num; // numar de careuri
  //stdin = "sudoku.in";

  fcin >> num;
  int i, j, v;
  for (int instance = 1; instance <= num; instance++) {
    fcout << "CAREU " << instance << ":\n";
    bool a[9][9][10];   // a[i,j,v]=true dc v = valoare posibila pt casuta i,j
    int s[9][9]; // stores the puzzle
    
    for (i=0; i<9; i++)  // incep cu valorile lui a toate = true
      for (j=0; j<9; j++)
	for (v=1; v<=9; v++)
	  a[i][j][v] = true;
    
    for (i=0; i<9; i++)  // citesc intrarea si construiesc a
      for (j=0; j<9; j++) {
	int entry;
	fcin >> entry;
	if (entry) fillin(a,s,i,j,entry);
	else s[i][j]=0;
      }
    if (!solve(a,s)) fcout << "FARA SOLUTIE\n";
  }

  fcout.close();
  fcin.close();
  
  return 0;
}