数独生成C++实现

来源:互联网 发布:数据库系统原理答案 编辑:程序博客网 时间:2024/05/18 02:00
// Sudo.cpp : 利用回溯思想生成数独终盘, 再随机抠去若干数字形成游戏(未证明游戏有唯一解)#include <IOSTREAM>#include <CTIME>using namespace std;int sudo[9][9], hole[9][9];bool set(int x, int y, int val){if (sudo[y][x] != 0)//非空return false;int x0, y0;for (x0=0; x0<9; x0++){if (sudo[y][x0] == val)//行冲突return false;}for (y0=0; y0<9; y0++){if (sudo[y0][x] == val)//列冲突return false;}for (y0=y/3*3; y0<y/3*3+3; y0++){for (x0=x/3*3; x0<x/3*3+3; x0++){if (sudo[y0][x0] == val) //格冲突return false;}}sudo[y][x] = val;return true;}void reset(int x, int y){sudo[y][x] = 0;}void initXOrd(int* xOrd)//0~9随机序列{int i, k, tmp;for (i=0; i<9; i++){xOrd[i] = i;}for (i=0; i<9; i++){k = rand() % 9;tmp = xOrd[k];xOrd[k] = xOrd[i];xOrd[i] = tmp;}}bool fillFrom(int y, int val){int xOrd[9];initXOrd(xOrd);//生成当前行的扫描序列for (int i=0; i<9; i++){int x = xOrd[i];if (set(x, y, val)){if (y == 8)//到了最后一行{if (val == 9 || fillFrom(0, val+1))//当前填9则结束, 否则从第一行填下一个数return true;} else{if (fillFrom(y+1, val))//下一行继续填当前数return true;}reset(x, y);//回溯}}return false;}void digHole(int holeCnt){int idx[81];int i, k;for (i=0; i<81; i++){hole[i / 9][i % 9] = 0;idx[i] = i;}for (i=0; i<holeCnt; i++)//随机挖洞位置{k = rand() % 81;int tmp = idx[k];idx[k] = idx[i];idx[i] = tmp;}for (i=0; i<holeCnt; i++){hole[idx[i] / 9][idx[i] % 9] = 1;}}void printSudo(){for (int y=0; y<9; y++){(y % 3 == 0) ? (cout << "------------------------\n ") : (cout << " ");for (int x=0; x<9; x++){(hole[y][x] == 0) ? (cout << sudo[y][x] << " ") : (cout << "  ");(x % 3 == 2) ? (cout << "| ") : (cout << "");}cout << endl;}cout << "------------------------\n";}int main(int argc, char* argv[]){ srand((unsigned)time(NULL));while (!fillFrom(0, 1)) ;digHole(35);printSudo();return 0;}

原创粉丝点击