# soj1107 Simple Puzzle 深搜枚举

Description

Here is a simple puzzle on numbers.

There are n numbers, each of which is of k (kn) distinct and significant digits. When the numbers are lined up in n rows keeping the digits in k columns, the n digits that appear in each column are also distinct. The sum of the numbers is known to be S.

One digit from each number is removed so that not more than one digit is removed from each column. The digits removed are all distinct. Thus n incomplete numbers are formed with remaining digits keeping digits in the original order. Given the incomplete numbers and the sum S, what are the original numbers?

Can you write a program that solves the simple puzzle? The program should find all possible solutions.

Input

Input consists of multiple test cases.
For each test case data is given in one line. The line contains the case number c, the given incomplete numbers followed by the sum S. A space separates two consecutive fields in input.
Input terminates with an input 0 for the case number c.

Output

For each test case, display output in one or more lines. Each line contains the case number c and a possible solution. A solution consists of the original numbers in the order in which the incomplete numbers appear in input. If there are more than one solution, first output the one with the smallest first number. If there is a tie, first output the one with the smallest second number and so on.
In case it is not possible to solve the puzzle, assume the solution to be 0 and display output accordingly.

Sample Input

1 6 8 174
2 53 81 817
3 3 4 130
0


Sample Output

1 0
2 536 281
3 36 94
3 83 47


#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
using namespace std;
int all[15];
int sum=0;
int n; //n个数
bool row[15];
bool isv[15];
vector<int> v;
vector<vector<int> > ans;
int m;     //m位数
void dfs(int deep){
if (v.size()==n){
//判重很重要啊！！！！！！！横竖都不相同
int sum1=0;
bool vvv[11][11]={0};
int ppp=m;
int tmp;
for (int i=0;i<n;i++){
sum1+=v[i];
int tmp=v[i],ttt;
int pp=0;
bool iss[10]={0};
while(tmp!=0){
ttt=tmp%10;
tmp/=10;
if (!iss[ttt]){
iss[ttt]=1;
}
else return;
if (!vvv[pp][ttt]){
vvv[pp][ttt]=1;
}
else return;
pp++;
}
}
if (sum1==sum){
//答案判重，应该是不需要的
/*
bool f=true;
bool f2=false;
for (int i=0;i<ans.size();i++){
f=true;
for (int j=0;j<ans[i].size()&&f;j++){
if (ans[i][j]!=v[j]) {
f=false;
}
}
if(f) {
f2=true;
break;
}
}
if (!f2) ans.push_back(v);*/
ans.push_back(v);
}
return ;
}

for (int i=0;i<10;i++){
if (!isv[i]){
isv[i]=1;
for (int j=0;j<=m;j++){
//原始数据没有前缀0
if (i==0&&j==m) continue;
if (!row[j]){
//插入一个数
row[j]=1;
int p=pow(10,j);
int a=all[deep];
int b=a%p;
a/=p;
int now=(a*10+i)*p+b;
v.push_back(now);
dfs(deep+1);
v.pop_back();
row[j]=0;
}
}
isv[i]=0;
}
}
}
bool cmp(vector<int> a,vector<int> b){
for (int i=0;i<a.size();i++){
if (a[i]!=b[i]){
return a[i]<b[i];
}
}
//return a[1]<b[1];
}
int main(){
string s;
int num;
while(getline(cin,s)){
if (s=="") continue;
memset(all,0,sizeof(all));
n=0;
int nu=0,num=0;
bool  f=true,f1=true;
int k=0;
for (int i=0;i<s.length();i++){
if (s[i]==' '){
if (f){
num=nu;
f=false;
k=0;
nu=0;
}
else {
if (f1) {
f1=false;
m=k;
}
k=0;
all[n++]=nu;
nu=0;
}
}
else {
k++;
nu=nu*10+s[i]-'0';
}
}
if (num==0) break;
sum=nu;
//只有一个sum输入时
if(n==0){
if (sum>=0&&sum<10)
cout<<num<<" "<<sum<<endl;
else cout<<num<<' '<<0<<endl;
continue;
}
memset(row,0,sizeof(row));
memset(isv,0,sizeof(isv));
v.clear();
ans.clear();
dfs(0);
if (ans.size()==0){
cout<<num<<' '<<0<<endl;
continue;
}
sort(ans.begin(),ans.end(),cmp);
for (int i=0;i<ans.size();i++){
cout<<num;
for (int j=0;j<n;j++){
cout<<" "<<ans[i][j];
}
cout<<endl;
}
}
}


﻿﻿

• 本文已收录于以下专栏：

举报原因： 您举报文章：soj1107 Simple Puzzle 深搜枚举 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)