Chinaunix

标题: 有 A B C D E F G H I J K ... 等N个数 [打印本页]

作者: xiangsiyu21945    时间: 2012-04-27 09:47
标题: 有 A B C D E F G H I J K ... 等N个数
本帖最后由 xiangsiyu21945 于 2012-04-27 13:51 编辑

有 A B C D E F G H I J K ... 等N个数字(字母取值范围是 1 到 9),列出在其中加如一个=号,任意多个加号组成一个等式的所有组合
       
像 AB + C + DEF = GH + I +J + K
或者A + B + CDE + FG = H + IJK

额,⊙﹏⊙b汗,求大家指点迷津,俺不会说话,谢谢啊!
************************************************************
就是从键盘输入N个数,每次输入的数是1到9之间的数,然后在 输入的N 个数之间 加一个 =  号,【若干】 + 号,组成一个【等式】,列出能组成 等式的组合
************************************************************

楼下说 = 号的位置 在1 到N/2 之间,说明 理解错题意了:
比如输入: 1  1  1  2  2  3  6  7                 1+1+1+2+2+3 = 6+7
作者: hgrany    时间: 2012-04-27 09:50
用C语言编写 或 给出思路


这口气....你是来给大家面试的吗?
作者: xiangsiyu21945    时间: 2012-04-27 09:53
额,我错了,我是来求大家指点的,指点一下思路
作者: frank529    时间: 2012-04-27 10:02
本帖最后由 frank529 于 2012-04-27 10:03 编辑

n个数,有n-1个间隔,放1个=号,0 ~ (n-2)个+号,穷举构造符号数组,分析等式是否成立
作者: koolcoy    时间: 2012-04-27 10:04
回复 4# frank529

这个问题明显穷举不行,指数级的复杂度。{:3_195:}
看看有没有啥好的dp算法
   
作者: enough_zerg    时间: 2012-04-27 10:08
从中间开始搞起

先把等号放最中间,发现左边大就把等号往左边移,反之则往右边动

直到移动到两个边界



作者: x5miao    时间: 2012-04-27 10:15
本帖最后由 x5miao 于 2012-04-27 10:15 编辑

什么叫A B C D等N个数字?字母的取值范围怎么是1至9

作者: xiangsiyu21945    时间: 2012-04-27 10:19
关键还包括了  AB + CD = E + F 这种类型,  1 ,2,3,4,4,6,  (  12 + 34 = 46)   ,现在 头都大了
作者: xishuaiya    时间: 2012-04-27 13:02
提供一个很粗糙的思路哈,也是最笨的方法:
“=”所在的位置为1~N/2
for(“=”号位置){
    当等号位置在n时,“=”前面有n个数字;
    使用n个数字、任意个+号,组合出等式
}

这样,问题就变为:怎么把n个数字用k个“+”号连接起来
作者: koolcoy    时间: 2012-04-28 09:25
这个问题有个重要的剪枝办法:等号左右两边除以3的余数必须相等。也就是等号两边的数字加起来除以3的余数必须相等。

剪枝是次要的,主要还是那个dp
作者: A.com    时间: 2012-04-28 11:17
并不是所有的序列都有解啊,譬如:1,1,1,1,1还不如出一个算24点的题呢
作者: hbmhalley    时间: 2012-04-28 12:33
回复 10# koolcoy


    除以3 -> 除以9

    还有,lz明明说的是 “A B C ...” 所以不超过26个数啥也不用管啊
作者: qishking    时间: 2012-05-02 20:40
hbmhalley 发表于 2012-04-28 12:33
回复 10# koolcoy
你这斯尽投机取巧
作者: lu18887    时间: 2012-05-02 21:22
xiangsiyu21945 发表于 2012-04-27 10:19
关键还包括了  AB + CD = E + F 这种类型,  1 ,2,3,4,4,6,  (  12 + 34 = 46)   ,现在 头都大了


这么复杂。。。
作者: starwing83    时间: 2012-05-03 10:58
本帖最后由 starwing83 于 2012-05-03 11:13 编辑

这个题本身不满足最优化原则,我也没找到能满足最优化原则的预处理,估计是不能dp了,老实搜索吧……下面是Lua版本的:
  1. local function dfs(t, lim)
  2.     local len = #t
  3.     local function search_(i, lim, a, b)
  4.         if i == lim then return coroutine.yield(a+b) end
  5.         search_(i+1, lim, a+b, t[i+1])
  6.         search_(i+1, lim, a, b*10+t[i+1])
  7.     end
  8.     local function iter(i, lim, a, b)
  9.         return coroutine.wrap(function() return search_(i, lim, a, b) end)
  10.     end
  11.     local results = {}
  12.     for lv in iter(1, lim, 0, t[1]) do
  13.         results[lv] = true
  14.     end
  15.     for rv in iter(lim+1, len, 0, t[lim+1]) do
  16.         if results[rv] then
  17.             return rv
  18.         end
  19.     end
  20. end

  21. local function print_result(t, lim, result)
  22.     local function search_(i, lim, a, b, way)
  23.         if i == lim then
  24.             if a+b == result then coroutine.yield(way..b) end
  25.             return
  26.         end
  27.         search_(i+1, lim, a+b, t[i+1], way..b.." + ")
  28.         search_(i+1, lim, a, b*10+t[i+1], way)
  29.     end
  30.     local function iter(i, lim, a, b)
  31.         return coroutine.wrap(function() return search_(i, lim, a, b, "") end)
  32.     end
  33.     for wl in iter(1, lim, 0, t[1]) do
  34.         for wr in iter(lim+1, #t, 0, t[lim+1]) do
  35.             print(wl.." = "..wr)
  36.         end
  37.     end
  38. end

  39. local function sum(t, a, b)
  40.     local s = 0
  41.     for i = a, b do
  42.         s = s + t[i]
  43.     end
  44.     return s
  45. end

  46. local function solve(t)
  47.     local len = #t
  48.     for i = 1, len-1 do
  49.         if sum(t, 1, i)%3 == sum(t, i+1, len)%3 then
  50.             local res = dfs(t, i)
  51.             if res then
  52.                 print_result(t, i, res)
  53.             end
  54.         end
  55.     end
  56. end

  57. solve {1, 1, 1, 2, 2, 3, 6, 7}
复制代码
输出:
lua  -- "noname\2012-05-03-1.lua"
1 + 1 + 12 + 2 = 3 + 6 + 7
1 + 11 + 2 + 2 = 3 + 6 + 7
11 + 1 + 2 + 2 = 3 + 6 + 7
Hit any key to close this window...

这个是找所有解的,只求一个解的看着加break吧……
作者: mpstat    时间: 2012-05-03 19:01
回复 15# starwing83


    这个是lua代码?
作者: koolcoy    时间: 2012-05-04 14:38
回复 15# starwing83

不懂lua,没看那个代码。

1. 除以9取余的那个剪枝还是值得做的。
2. N稍微大一点,穷搜就不行: 把等号的位置放下后,剩下的每两个数字之间的加号可有可无,总共2^(N-2)总可能性,指数级的复杂度,穷搜显然不现实。
   
作者: 控球之魂    时间: 2012-05-06 13:12

没看出有啥很明显的polynomial time的算法 , 干脆把所有情况都做一下, 指数级别复杂度。  
几年没写过程序了, 纯粹练习下基本语法,循环。

  1. #include <iostream>
  2. #include <vector>
  3. #include <ctime>
  4. #include <cstdlib>
  5. using namespace std;

  6. vector<int> generateSample(int size) {
  7.     srand ( time(NULL) );
  8.     vector<int> sample(size);
  9.     for(int i=0; i < size; i++)
  10.         sample[i] = rand() % 9 + 1;
  11.     return sample;
  12. }

  13. void print(vector<int> vec) {
  14.         for(int i=0; i < vec.size(); i++)
  15.                 cout << vec[i] << " ";
  16.         cout << endl;
  17. }

  18. void print(vector<vector<int> > vec) {
  19.         for(int i = 0; i < vec.size(); i++)
  20.                 print(vec[i]);
  21. }

  22. void generateAllCombination_aux(vector<int> sample, vector<vector<int> > & allcomb) {
  23.         if (sample.size() == 1)
  24.                 allcomb.push_back(sample);
  25.         else {
  26.                 vector<int> sub(sample.begin(), sample.end());
  27.                 int tail = sub.back();
  28.                 sub.pop_back();
  29.                 generateAllCombination_aux(sub, allcomb);
  30.                 int currSize = allcomb.size();
  31.                 for(int i = 0; i < currSize; i++) {
  32.                         allcomb.push_back(allcomb[i]);
  33.                         int tmp = allcomb[currSize + i].back();
  34.                         allcomb[currSize + i].pop_back();
  35.                         allcomb[currSize + i].push_back(tmp*10 + tail);
  36.                         allcomb[i].push_back(tail);
  37.                 }
  38.         }
  39. }

  40. vector<vector<int> > generateAllCombination(vector<int> sample) {
  41.         vector<vector<int> > allcomb;
  42.         generateAllCombination_aux(sample, allcomb);
  43.         return allcomb;
  44. }

  45. int sum(vector<int> vec) {
  46.         int total = 0;
  47.         for(int i = 0; i < vec.size(); i++)
  48.                 total += vec[i];       
  49.         return total;
  50. }

  51. void printPlus(vector<int> vec) {
  52.         for(int i = 0; i < vec.size() - 1; i ++)
  53.                 cout << vec[i] << " + ";
  54.         cout << vec.back();
  55. }

  56. void solve(vector<vector<int> > left, vector<vector<int> > right) {
  57.         for(int i = 0; i < left.size(); i++)
  58.                 for(int j=0; j < right.size(); j++)
  59.                         if (sum(left[i]) == sum(right[j])) {
  60.                                 printPlus(left[i]);
  61.                                 cout << " = ";
  62.                                 printPlus(right[j]);
  63.                                 cout << endl;
  64.                         }
  65. }

  66. void solve(vector<int> sample) {
  67.         for (int pivot = 1; pivot < sample.size(); pivot++) {
  68.                 vector<int> left(sample.begin(), sample.begin() + pivot);
  69.                 vector<int> right(sample.begin() + pivot, sample.end());
  70.                 vector<vector<int> > leftAllComb = generateAllCombination(left);
  71.                 vector<vector<int> > rightAllComb = generateAllCombination(right);
  72.                 solve(leftAllComb, rightAllComb);
  73.         }
  74. }

  75. int main() {
  76.         vector<int> sample = generateSample(12);
  77.         cout << "sample : ";
  78.         print(sample);  
  79.         cout << endl;
  80.         solve(sample);  
  81.        
  82.         return 0;
  83. }

复制代码
min@min-PC ~/temp
$ ./a.exe
sample : 4 5 3 3 1 6 7 4 4 4 9 8

4 + 5 + 3 + 3 + 1 + 6 + 7 = 4 + 4 + 4 + 9 + 8
45 + 3 + 3 + 1 + 6 + 7 = 44 + 4 + 9 + 8
45 + 3 + 3 + 1 + 6 + 7 = 4 + 44 + 9 + 8
45 + 3 + 3 + 1 + 6 + 7 = 4 + 4 + 49 + 8
4 + 53 + 31 + 6 + 7 = 44 + 49 + 8
4 + 5 + 33 + 16 + 7 = 44 + 4 + 9 + 8
4 + 5 + 33 + 16 + 7 = 4 + 44 + 9 + 8
4 + 5 + 33 + 16 + 7 = 4 + 4 + 49 + 8
45 + 33 + 16 + 7 = 44 + 49 + 8
4 + 5 + 33 + 1 + 67 = 4 + 4 + 4 + 98
45 + 33 + 1 + 67 = 44 + 4 + 98
45 + 33 + 1 + 67 = 4 + 44 + 98
4 + 5 + 3 + 31 + 67 = 4 + 4 + 4 + 98
45 + 3 + 31 + 67 = 44 + 4 + 98
45 + 3 + 31 + 67 = 4 + 44 + 98

min@min-PC ~/temp
$ ./a.exe
sample : 9 8 1 3 2 2 5 9 7 4 8 4






欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2