数独
昨天给数独游戏这题出个数据,看了看网上代码有点少,所以就自己操作了一下(可能有地方操作不到位,望见谅!代码功底不是很好!
废话不多上那就直接上代码了!
生成代码
- 代码有些地方都加了注释,生成速度还是蛮快的,
- 原本rand的想使用C++的mt19937,可是不太会用
#include <bits/stdc++.h>
using namespace std;
char mp[9][9];
int flag = 0;
//检查函数
bool check(int x,int y,char k){
//检查行
for(int i = 0 ; i < 9 ; i ++){
if(mp[x][i] == k)
return false;
}
//检查列
for(int i = 0 ; i < 9 ; i ++){
if(mp[i][y] == k)
return false;
}
//检查九宫格
for(int i = x / 3 * 3 ; i < x / 3 * 3 + 3 ; i ++){
for(int j = y / 3 * 3 ; j < y / 3 * 3 + 3 ; j ++){
if(mp[i][j] == k)
return false;
}
}
return true;
}
//搜索函数
bool dfs(){
for(int i = 0 ; i < 9 ; i ++){
for(int j = 0 ; j < 9 ; j ++){
if(mp[i][j] != '?')
continue;
else{
for(char k = '1' ; k <= '9' ; k ++){
if(check(i,j,k)){
mp[i][j] = k;
if(dfs())
return true;
else
mp[i][j] = '?';
}
}
return false;
}
}
}
return true;
}
class cShuDu {
static const int MAXN = 15;
bool vis[MAXN][MAXN][MAXN]{}; // 标记每个3x3里出现了哪些数字
bool vis_x[MAXN][MAXN]{}; // 标记行里出现了哪些数字
bool vis_y[MAXN][MAXN]{}; // 标记列里出现了哪些数字
char cmap[MAXN * MAXN]{}; // 地图
int num{}; // 需要生成的个数
int sum[MAXN]{};
vector<int> randVe; // 随机1-9 顺序打乱
vector<vector<char> > mapVe; // 存放地图
void randNum9() {
for(int i = 1; i <= 222; i++){
int l = rand() % 9, r = rand() % 9;
// cout << l << " " << r << endl;
swap(randVe[l], randVe[r]);
}
// cout << "-------------------------------" << endl;
// for(auto i : randVe) {
// cout << i << " ";
// }
// cout << endl;
// cout << "-------------------------------" << endl;
}
void print(int now) {
for(int i = 1; i <= 81; i++){
mapVe[now].push_back(cmap[i]);
}
}
bool check(int xx, int yy, int val) {
return !(vis[(xx + 2) / 3][(yy + 2) / 3][val] || vis_x[xx][val] || vis_y[yy][val] || sum[val] >= 9);
}
void dfs(int now, int cnt) {
if(num == 0) return ;
if(now == 82) {
num--;
print(cnt - 1);
return ;
}
randNum9(); //打乱1-9
for(auto j : randVe) {
int xx = (now + 8) / 9;
int yy = (now - 1) % 9 + 1;
if(check(xx, yy, j)) {
vis[(xx + 2) / 3][(yy + 2) / 3][j] = vis_x[xx][j] = vis_y[yy][j] = true;
cmap[now] = char ('0' + j);
sum[j]++;
dfs(now + 1, cnt);
if(num == 0) return ;
sum[j]--;
vis[(xx + 2) / 3][(yy + 2) / 3][j] = vis_x[xx][j] = vis_y[yy][j] = false;
cmap[now] = '\0';
}
}
}
public:
void init() {
memset(vis, false, sizeof(vis));
memset(vis_x, false, sizeof(vis_x));
memset(vis_y, false, sizeof(vis_y));
memset(cmap, '\0', sizeof(cmap));
memset(sum, 0, sizeof(sum));
randVe.clear();
for(int i = 1; i <= 9; i++) randVe.push_back(i);
}
vector<vector<char> > getShuDu(int _num) {
mapVe.clear();
mapVe.resize(_num + 5);
for(int i = 1; i <= _num; i++){
init();
num = 1;
dfs(1, i);
}
return mapVe;
}
};
int main()
{
ios::sync_with_stdio(false);
// ifstream fileIn;
ofstream fileIn, fileOut;
srand(time(0));
for(int i = 1; i <= 20; i++){
int num = rand() % 6666 + 5555;
// int num = 1;
cShuDu tmp;
vector<vector<char> > ve = tmp.getShuDu(num);
// 输出 in
fileIn.open("data" + to_string(i) + ".in", ios::out);
for(int j = 0; j < num; j++){
int now = 0;
cout << "*********************" << endl;
int maxn = 80; // 最大问号数
for(auto &t : ve[j]) {
now++;
if(now % 9 != 1) {
fileIn << " ";
cout << " ";
}
if((rand() + now) % 5 == 0 && maxn > 0) {
t = '?';
maxn--;
}
fileIn << t;
cout << t;
if(now % 9 == 0) {
fileIn << endl;
cout << endl;
}
}
cout << "*********************" << endl;
}
fileIn.close();
// 输出out
fileOut.open("data" + to_string(i) + ".out", ios::out);
for(int j = 0; j < num; j++) {
int now = 0;
cout << "*********************" << endl;
for(auto t : ve[j]) {
now++;
mp[(now - 1) / 9][(now - 1) % 9] = t;
}
dfs();
for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
if(y != 0) {
cout << " ";
fileOut << " ";
}
fileOut << mp[x][y];
cout << mp[x][y];
}
fileOut << endl;
cout << endl;
}
cout << "*********************" << endl;
if(j != num - 1) {
fileOut << endl;
cout << endl;
}
}
fileOut.close();
}
return 0;
}
HUSTOJ的spj
#include <bits/stdc++.h>
using namespace std;
char user_map[25][25];
char oj_map[25][25];
bool xx[25][25], yy[25][25], vis[25][25][25];
int main(int argc, char* argv[]) {
FILE * f_in=fopen(argv[1],"r");//测试输入
FILE * f_out=fopen(argv[2],"r");//测试输出
FILE * f_user=fopen(argv[3],"r");//用户输出
int ret=0; //AC=0,WA=1
/*****spj代码区域*******/
while(fgets(oj_map[1], 25, f_in) != NULL) {
memset(xx, false, sizeof(xx));
memset(yy, false, sizeof(yy));
memset(vis, false, sizeof(vis));
for(int i = 2; i <= 9; i++){
fgets(oj_map[i], 25, f_in);
}
for(int i = 1; i <= 10; i++){
fgets(user_map[i], 25, f_user);
}
for(int i = 1; i <= 9; i++){
for(int j = 0; j < 18; j += 2) {
int tmp = (j + 2) / 2;
if(oj_map[i][j] == '?') {
;
}
else{
if(oj_map[i][j] != user_map[i][j]){
ret = 1;
}
}
if(vis[(i + 2) / 3][(tmp + 2) / 3][user_map[i][j] - '0'] || xx[i][user_map[i][j] - '0'] || yy[tmp][user_map[i][j] - '0']){
ret = 2;
}
vis[(i + 2) / 3][(tmp + 2) / 3][user_map[i][j] - '0'] = xx[i][user_map[i][j] - '0'] = yy[tmp][user_map[i][j] - '0'] = true;
}
}
}
/*****spj-end********/
fclose(f_in);
fclose(f_out);
fclose(f_user);
return ret;
}