github项目地址 https://github.com/0317023632/031702632
psp表格
解题思路
我是只选择做了3宫格,本来打算把在把文件输入输出函数搞懂后,在升级算法实现九宫格,然而本人太菜,理解应用fopen,fscanf等等搞了好几天,最后没时间就只实现了3宫格。说下我的思路,我的解题算法只用了两个,一个是isSole函数,用于判断数字的唯一性。一个是回溯函数,这个函数将三宫格中为零的数字从一到三赋值再调用唯一性函数判断唯一性。
设计实现过程
唯一性函数
bool isSole(int count)
{
int row = count / 3;
int col = count % 3;
int j;
//同一行
for (j = 0; j < 3; ++j)
{
if (map[row][j] == map[row][col] && j != col)
{
return false;
}
}
//同一列
for (j = 0; j < 3; ++j)
{
if (map[j][col] == map[row][col] && j != row)
{
return false;
}
}
return true;
}
回溯函数
void backtrace(int count)
{
if (count == 9)
{
flag=1;
return;//一个盘面解答完成
}
else{
int row = count / 3;
int col = count % 3;
if (map[row][col] == 0)
{
for (int i = 1; i <= 3; ++i)
{
map[row][col] = i;//赋值
if (isSole(count))
{//可以放
backtrace(count + 1);//进入下一层
if(flag=1)
return;
}
}
map[row][col] = 0;//回溯
}
else {
backtrace(count + 1);//进入下一个格子
}
}
}
全部代码
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include <iostream>
#include <algorithm>
#pragma warning(disable:4996)
using namespace std;
int map[3][3];
int flag=0;
bool isSole(int count)
{
int row = count / 3;
int col = count % 3;
int j;
//同一行
for (j = 0; j < 3; ++j)
{
if (map[row][j] == map[row][col] && j != col)
{
return false;
}
}
//同一列
for (j = 0; j < 3; ++j)
{
if (map[j][col] == map[row][col] && j != row)
{
return false;
}
}
return true;
}
void backtrace(int count)
{
if (count == 9)
{
flag=1;
return;//一个盘面解答完成
}
else{
int row = count / 3;
int col = count % 3;
if (map[row][col] == 0)
{
for (int i = 1; i <= 3; ++i)
{
map[row][col] = i;//赋值
if (isSole(count))
{//可以放
backtrace(count + 1);//进入下一层
if(flag=1)
return;
}
}
map[row][col] = 0;//回溯
}
else {
backtrace(count + 1);//进入下一个格子
}
}
}
int main(int argc,char *argv[])
{
FILE *fp1;
FILE *fp2;
int i,t,k,j;
t = atoi(argv[4]);
//打开文件
fp1 = fopen(argv[6], "r");
//检验是否打开失败
if (fp1 == NULL)
return -1;
fp2 = fopen(argv[8], "w");
if (fp2 == NULL)
return -1;
for (k = 0; k < t; k++)//次数
{
i = 0; j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
fscanf(fp1, "%d", &map[i][j]);//将第一个盘面的数据输入进数组
}
}
backtrace(0);//回溯得出第一个盘面的答案
for(i=0;i<3;i++){
for(j =0;j<3;j++){
cout<<map[i][j]<<" ";
}
cout<<endl;
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
fprintf(fp2, "%d", map[i][j]);//将第一个盘面的答案存入输出文件
if (j != 2)
fprintf(fp2, "%c", ' ');
}
if(i!=2)
fprintf(fp2, "%c", '
');
}
if(k!=t-1)
fprintf(fp2, "%s","
");
}
//关闭文件
fclose(fp1);
//检验文件是否关闭失败
if (fp1 == NULL)
return -1;
fclose(fp2);
if (fp1 == NULL)
return -1;
return 0;
}
个人收获
这次学到了挺多东西的,诸如fopen,fscanf等文件输入输出函数,还有回溯函数,vs自带的性能分析器。万恶的文件输入输出函数一加入原来的代码里就bug百出,自己看了半天又找了同学讨论了好久才把他搞定。由于自己没有安排好时间,只完成了三宫格,其余的一些东西也没搞好。。。这是一次教训,下次希望能吸取教训合理安排好时间。