bool dlx(int k)  {
    if(R[head]==head) { //È«²¿ÌîÍê
        ans();
        return true;
    }
    int s=INF,c; //ÕÒ1×îÉÙµÄÁжÔÓ¦µÄµÚÒ»¸ö1µÄλÖÃi
    for(int i=R[head];i!=head;i=R[i])
        if(S[i]<s) s=S[i],c=i;

    remove(c); //ɾ³ýc¶ÔÓ¦µÄÁÐ
    for(int i=D[c];i!=c;i=D[i]) {
        int x = to[row[i]][0] , y = to[row[i]][1], z = to[row[i]][2];
        sudoku[x][y] = z;
        for(int j=R[i];j!=i;j=R[j]) remove(C[j]); //ɾ³ýÄÇÒ»ÐÐÓÐ1µÄÁÐ
        if(dlx(k+1)) return true;
        for(int j=L[i];j!=i;j=L[j]) resume(C[j]); //»Ö¸´ÄÇÒ»ÐÐÓÐ1µÄÁÐ
    }
    resume(c); //»Ö¸´c¶ÔÓ¦µÄÁÐ
    return false;
}
Esempio n. 2
0
void dlx(int k) {
    if(k+h()>= ans) return;
    if(R[head]==head) {
        ans = min(ans,k);
        return;
    }

    int s=INF,c;
    for(int i=R[head];i!=head;i=R[i]){
        if(S[i]<s) s=S[i],c=i;
    }

    for(int i=D[c];i!=c;i=D[i]) {
        remove(i);
        for(int j=R[i];j!=i;j=R[j]) remove(j);
        dlx(k+1);
        for(int j=L[i];j!=i;j=L[j]) resume(j);
        resume(i);
    }
}
bool dlx(int k){
    if(R[head] == head){
        return true;
    }
    int s = INF,c;
    for(int i = R[head];i!=head ; i = R[i]){
        if(S[i] < s ) s = S[i] ,c = i;
    }
    
    remove(c);
    for(int i = D[c] ; i != c; i = D[i]){
        
        int tt = row[i];
        sudoku[ to[tt][0] ][ to[tt][1] ] = to[tt][2];
         for(int f= R[i];f != i ; f = R[f])    remove(C[f]);
        if(dlx(k+1)) return true;
        for(int f= L[i]; f != i ; f = L[f]) resume(C[f]);
    }
    resume(c);
    return false;
}
Esempio n. 4
0
bool dlx(int k)  {
	if(R[head]==head) { //全部填完
		//输出选择了哪些行
		cout << k ;
		for(int i=0;i<k ;i++) cout << " " << row[O[i]];
		cout << endl;
		return true;
	}
	int s=INF,c; //找1最少的列对应的第一个1的位置i
	for(int i=R[head];i!=head;i=R[i])
		if(S[i]<s) s=S[i],c=i;

	remove(c); //删除c对应的列
	for(int i=D[c];i!=c;i=D[i]) {
		O[k]=i;
		for(int j=R[i];j!=i;j=R[j]) remove(C[j]); //删除那一行有1的列
		if(dlx(k+1)) return true;
		for(int j=L[i];j!=i;j=L[j]) resume(C[j]); //恢复那一行有1的列
	}
	resume(c); //恢复c对应的列
	return false;
}
Esempio n. 5
0
void solve_sudoku(){
	int ji = 0;
	int m = 27*9 + 81;
	int sh = 1,ss = 82,sk = 163,sg = 244;		// 行 竖 块 
	init(m);
	for(int i = 0;i < 9;i++)
		for(int f = 0;f < 9;f++)
			for(int g = 0;g < 9;g++){
				to[ji][0] = i;
				to[ji][1] = f;
				to[ji][2] = g;
				
				if(-1==sudoku[i][f] || g==sudoku[i][f]){
					addnode(ji,sh+ mul(i,g));
					addnode(ji,ss+ mul(f,g));
					addnode(ji,sk+ mul( getkuai(i,f),g ));
					addnode(ji,sg+ mul(i,f));
				}
				ji++;
			}
	dlx(0);
}
void solve_sudoku(){
    init(27*9 + 81);
    int nn = 0;
    for(int i = 0 ; i< 9 ;i++)
        for(int f = 0 ;f < 9;f++)
            for(int g= 0 ; g< 9; g++){
                to[nn][0] = i;
                to[nn][1] = f;
                to[nn][2] = g;
                
                if(-1==sudoku[i][f] || g==sudoku[i][f]){
                    addnode(nn,1+mul(i,g));
                    addnode(nn,82+mul(f,g));
                    addnode(nn,163+ mul( getkuai(i,f),g) );
                    addnode(nn,244+ mul(i,f));
                }
                nn++;
            }
    if(false == dlx(0))
        cout << "impossible" << endl;
    else 
        ans();
}
bool dlx(int k)  {
    if(R[head]==head) { //È«²¿ÌîÍê
        return true;
    }
    int s=INF,c; //ÕÒ1×îÉÙµÄÁжÔÓ¦µÄµÚÒ»¸ö1µÄλÖÃi
    for(int i=R[head];i!=head;i=R[i])
        if(S[i]<s) s=S[i],c=i;

    remove(c); //ɾ³ýc¶ÔÓ¦µÄÁÐ
    for(int i=D[c];i!=c;i=D[i]) {
        int num = to[row[i]][0];
        int s = to[row[i]][1];
        int t = to[row[i]][2];

        res[num][0] = s;
        res[num][1] = t;

        for(int j=R[i];j!=i;j=R[j]) remove(C[j]); //ɾ³ýÄÇÒ»ÐÐÓÐ1µÄÁÐ
        if(dlx(k+1)) return true;
        for(int j=L[i];j!=i;j=L[j]) resume(C[j]); //»Ö¸´ÄÇÒ»ÐÐÓÐ1µÄÁÐ
    }
    resume(c); //»Ö¸´c¶ÔÓ¦µÄÁÐ
    return false;
}
bool solve(){
    init(n*d + n);
    int nn = 0;
    for(int i = 0 ; i < n ;i++) { 
        for(int f = t[i][0]; f <= t[i][1] ;f++)
            for(int g = f; g<= t[i][1] ;g++){
                to[nn][0] = i;
                to[nn][1] = f;
                to[nn][2] = g;
                addnode(nn, n*d+1+i);
                for(int h = 0; h < n;h++)
                    if(1 == con[i+1][h+1] || i == h)
                        for(int j = f;j <= g;j++)
                            addnode(nn,mul(h,j-1)+1);
                nn++;
            }
        to[nn][0] = i;
        to[nn][1] = 0;
        to[nn][2] = 0;
        addnode(nn,n*d + 1 + i);
        nn++;
    }
    return dlx(0);
}
Esempio n. 9
0
 Dlp Frame::dxy() const { return y() <= dlx(); }      ///< xy dual plane
Esempio n. 10
0
 /* Homogenous Planes in Conformal Space */
 Dlp Frame::dxz() const  { return -z() <= dlx(); }    ///< xz dual plane
Esempio n. 11
0
Sudoku SudokuSolver::solve_impl(const Sudoku& sudoku, bool randomized) const {
  if (!sudoku.is_valid()) {
    throw std::runtime_error("solve(): Invalid sudoku");
  }

  const SudokuType& type = sudoku.type();
  unsigned n = type.n();
  auto pack = [&](unsigned a, unsigned b) -> unsigned { return a * n + b; };
  auto id_cell = [&](unsigned x, unsigned y) -> unsigned { return pack(x, y); };
  auto id_col = [&](unsigned x, unsigned d) -> unsigned { return type.size() + pack(x, d); };
  auto id_row = [&](unsigned y, unsigned d) -> unsigned { return 2 * type.size() + pack(y, d); };
  auto id_region = [&](unsigned i, unsigned d) -> unsigned { return 3 * type.size() + pack(i, d); };

  std::vector<unsigned> cell_taken(type.size());
  std::vector<unsigned> col_taken(type.size());
  std::vector<unsigned> row_taken(type.size());
  std::vector<unsigned> region_taken(type.size());
  for (unsigned i = 0; i < type.size(); ++i) {
    if (sudoku[i] != 0) {
      unsigned x = i % n;
      unsigned y = i / n;
      unsigned d = sudoku[i] - 1;
      ++cell_taken[pack(x, y)];
      ++col_taken[pack(x, d)];
      ++row_taken[pack(y, d)];
      ++region_taken[pack(type.region(x, y), d)];
    }
  }

  std::vector<std::vector<unsigned>> matrix;
  for (unsigned i = 0; i < n; ++i) {
    for (unsigned j = 0; j < n; ++j) {
      if (cell_taken[pack(i, j)]) matrix.push_back({id_cell(i, j)});
      if (col_taken[pack(i, j)]) matrix.push_back({id_col(i, j)});
      if (row_taken[pack(i, j)]) matrix.push_back({id_row(i, j)});
      if (region_taken[pack(i, j)]) matrix.push_back({id_region(i, j)});
    }
  }

  std::unordered_map<unsigned, unsigned> row_position, row_digit;
  for (unsigned y = 0; y < n; ++y) {
    for (unsigned x = 0; x < n; ++x) {
      for (unsigned d = 0; d < n; ++d) {
        if (cell_taken[pack(x, y)]
            || col_taken[pack(x, d)]
            || row_taken[pack(y, d)]
            || region_taken[pack(type.region(x, y), d)])
        {
          continue;
        }
        unsigned row_index = matrix.size();
        row_position[row_index] = y * n + x;
        row_digit[row_index] = d;
        matrix.push_back({
          id_cell(x, y),
          id_col(x, d),
          id_row(y, d),
          id_region(type.region(x, y), d)
        });
      }
    }
  }

  AlgorithmDLX dlx(ExactCoverProblem(4 * type.size(), matrix));
  auto options = AlgorithmDLX::Options();
  if (randomized) {
    static std::random_device rd;
    static auto engine = std::mt19937(rd());
    options.choose_random_column = randomized;
    options.random_engine = &engine;
  }
  options.max_solutions = randomized ? 1 : 2;
  auto result = dlx.search(options);
  auto solutions = std::vector<Sudoku>();
  for (const auto& rows : result.solutions) {
    Sudoku solved(sudoku);
    for (auto i : rows) {
      auto pos = row_position.find(i);
      if (pos != row_position.end()) {
        solved[pos->second] = row_digit[i] + 1;
      }
    }
    solutions.push_back(std::move(solved));
  }

  if (solutions.empty()) {
    throw std::runtime_error("No solution");
  }
  if (solutions.size() > 1) {
    throw std::runtime_error("Multiple solutions");
  }
  return solutions[0];
}