坑
输出格式十分蛋疼,题目还不说清楚,难道指望我能从vj的output排版看懂输出格式?全靠uDebug。懒得弄明白了,如果你也因为格式过不去,直接抄我的吧……
思路简述
一道状态空间搜索题。用dfs从上到下一行一行地搜索,每一行从左到右dfs两种状态——横竖放置骨牌,并将骨牌编号填充至ans数组保存,直至本行没有空位,此时列数+1后==maxc,判断是搜索下一行,还是已经填充完了ans直接输出答案
AC代码
#include <iostream>
#include <cstring>
#include <iomanip>// setw()设置紧跟在后面的字段的输出宽度
//#define test
using namespace std;
const int maxr=7,maxc=8,maxb=28+1;// 最大行列数,最大牌数加一
int pips[maxr][maxc];
int ans[maxr][maxc];
bool bones[maxb][maxb];
// pips=>Bone
int id[7][7];// pips对应的牌的编号
int Bone;// 牌的编号
int cnt;
void dfs(int row,int col){
if(col==maxc){
// 填充完毕
if(row==maxr-1){
++cnt;
for(int i=0;i<maxr;i++){
for(int j=0;j<maxc;j++){
// if(ans[i][j]<10) cout<<" ";
// cout<<" "<<ans[i][j];
cout<<setw(4)<<ans[i][j];// 设置输出宽度,不足则前补空格
if(j==maxc-1) cout<<"\n";
}
}
cout<<"\n\n";
}
// 下一行
else{ dfs(row+1,0);}
return;
}
// 若格子已被上一行的竖着的占用
if(ans[row][col]!=0){
// 往后找空位;若找不到,就会进入上面的col==maxc
for(int i=col+1;i<=maxc;i++){
if(i==maxc || ans[row][i]==0){
dfs(row,i);
return;
}
}
}
// 横放
if(col+1<maxc){
// 右边格子是否被占用,否,则检查有没有牌
if(ans[row][col+1]==0){
int idx1=pips[row][col],idx2=pips[row][col+1];
if(bones[idx1][idx2]){
bones[idx1][idx2]=false;
bones[idx2][idx1]=false;
ans[row][col]=id[idx1][idx2];
ans[row][col+1]=id[idx1][idx2];
dfs(row,col+2);
// 回复
bones[idx1][idx2]=true;
bones[idx2][idx1]=true;
ans[row][col]=0;
ans[row][col+1]=0;
}
}
}
//竖放
if(row+1<maxr){
// 下方格子不可能被占用,只检查有没有牌
int idx1=pips[row][col],idx2=pips[row+1][col];
if(bones[idx1][idx2]){
bones[idx1][idx2]=false;
bones[idx2][idx1]=false;
ans[row][col]=id[idx1][idx2];
ans[row+1][col]=id[idx1][idx2];
dfs(row,col+1);
// 回复
bones[idx1][idx2]=true;
bones[idx2][idx1]=true;
ans[row][col]=0;
ans[row+1][col]=0;
}
}
}
void solve(){
memset(bones,-1,sizeof(bones));// 起初,牌都有(true)
memset(ans,0, sizeof(ans));// 未填充的标记为0
dfs(0,0);
}
int main(){
#ifdef test
freopen("D:\\college\\clionworkplace\\test_c++2\\in.txt","r",stdin);
freopen("D:\\college\\clionworkplace\\test_c++2\\out.txt","w",stdout);
#endif
int kase=1;
bool first=true;
// pips=>Bone
Bone=1;
for(int i=0;i<7;i++){
for(int j=i;j<7;j++){
id[i][j]=Bone;
id[j][i]=Bone++;
}
}
while (cin>>pips[0][0]){
cnt=0;
for(int i=0;i<maxr;i++){
for(int j=0;j<maxc;j++){
if(i==0 && j==0) continue;
cin>>pips[i][j];
}
}
if(!first) cout<<"\n\n\n\n\n";
first=false;
cout<<"Layout #"<<kase<<":\n\n\n";
for(int i=0;i<maxr;i++){
for(int j=0;j<maxc;j++){
cout<<setw(4)<<pips[i][j];// 设置输出宽度,不足则前补空格
if(j==maxc-1) cout<<"\n";
}
}
cout<<"\n"<<"Maps resulting from layout #"<<kase<<" are:\n\n\n";
solve();
cout<<"There are "<<cnt<<" solution(s) for layout #"<<kase++<<".\n";
}
return 0;
}