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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值