sicily 1107. Simple Puzzle

1107. Simple Puzzle

Constraints

Time Limit: 10 secs, Memory Limit: 32 MB

Description

Here is a simple puzzle on numbers.

There are n numbers, each of which is of k (k$ \ge$n) 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

题目分析

若干个数,每一列的值都不同,
将每个数的去掉一个位,这个位在不同列且值不同
根据残缺的数字和完整的和恢复数据,按照前序因子从小到大输出
深搜题,注意前缀0


#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

std::string s;
std::string factors[100];
std::vector<std::string> ans;
int sum;
int count;
bool location[10];
bool digit[10];

void getSum() {
   int weight = 1;
   sum = 0;
   for (int c = factors[count - 1].size() - 1; c >= 0; --c) {
      sum += (factors[count - 1][c] - '0') * weight;
      weight *= 10;
   }
}

void init() {
   count = 0;
   factors[0] = "";
   for (int c = 0; c < s.size(); ++c) {
       if (s[c] == ' ') {
          factors[++count] = "";
       } else {
          factors[count] += s[c];
       }
   }
   count++;
   for (int c = 1; c < count - 1; ++c)
      std::reverse(factors[c].begin(), factors[c].end());

   memset(location, false, sizeof(location));
   memset(digit, false, sizeof(digit));
   if (!ans.empty())
     ans.clear();
   getSum();
}

void check() {
   for (int c = 0; c < 11; ++c) {
     int num[10] = {0};    
     for (int d = 1; d <= count - 2; ++d) {
       if (c < factors[d].size()) {
         if (num[factors[d][c] - '0'] == 1)
           return;
         else
           num[factors[d][c] - '0'] = 1; 
       }
     }
   }
     
   int temp = 0;
   for (int d = 1; d < count - 1; ++d) {
      int aaa = 0;
      int weight = 1;
      for (int c = 0; factors[d][c] != '\0'; ++c) {
         aaa += (factors[d][c] - 48) * weight;
         weight *= 10;
      }
      temp += aaa;
   }

   if (temp == sum) {
     std::string ss = factors[0];
     for (int c = 1; c < count - 1; ++c) {
        ss  += " ";
        bool pre = false;
        std::string sss = factors[c];
        std::reverse(sss.begin(), sss.end());
        for (int d = 0; sss[d] != '\0'; ++d) {
           if (sss[d] > '0') {
             ss += sss[d];
             pre = true;
           } else {
             if (pre)
               ss += sss[d];
           }
        }
        if (pre == false)
          ss += '0';
     }
     ans.push_back(ss);
   }
}

std::string insert(std::string ss, int loc, int dig) {
   char a = 48 + dig;
   std::string temp = "";
   if (loc == 0) {
     temp += a;
     temp += ss;
   } else {
     int c;
     for (c = 0; c < loc && ss[c] != '\0'; ++c)
        temp += ss[c];
     temp += a;
     for (; ss[c] != '\0'; ++c)
        temp += ss[c];
   }
   return temp;
}

void dfs(int num) {
   if (num == count - 1) {
     check();
   } else {
     std::string temp = factors[num];
     for (int c = 0; c <= temp.size(); ++c) {
        if (location[c] == true)
           continue;
        location[c] = true;
        for (int d = 0; d <= 9; ++d) {
           if (digit[d] == true)
             continue;
           digit[d] = true;
           factors[num] = insert(temp, c, d);
           dfs(num + 1);
           digit[d] = false;
        }
        location[c] = false;
     }
     factors[num] = temp;
   }
}

void print() {
   if (ans.empty()) {
     std::cout << factors[0] << " 0" << std::endl;
   } else {
     std::sort(ans.begin(), ans.end());
     for (int c = 0; c < ans.size(); ++c)
        std::cout << ans[c] << std::endl;
   }
}

int main() {
  while (1) {
      getline(std::cin, s);
      if (s == "0")
        break;

      init();
      dfs(1);
      print();
  }
  return 0;
}


你可能感兴趣的:(sicily 1107. Simple Puzzle)