等式变换

输入一个正整数X,在下面的等式左边的数字之间添加+号、-号或空格,使得等式成立。

1 2 3 4 5 6 7 8 9 = X

比如:

12-34+5-67+89 = 5

1+23+4-5+6-7-8-9 = 5

请编写程序,统计满足输入整数的所有整数个数。

输入:       正整数,等式右边的数字

输出:       使该等式成立的个数

样例输入:5

样例输出:21(此处经大家提醒已更正)

这里我理解错了题目意思,以为是1前面也加+/-。思路没什么影响,从结果中去掉最开始一位为 -号的就行。

本方法的思路是:每个数字(除1之外)的所有数字前的符号都有三种选项:+/-/空,"空"代表不加符号,也就是与前一个数字相连。

将所有数字的符号用一个三进制的数来表示,用0代表+,1代表-,2代表空。21201202,就代表12-34+5-67+89。代码中由于计算三进制的方便,将其以倒序的方式表示的,且1前面可以用+/-号,三进制通过一个int型的数字转换成了string。

  于是,从0到22222222就可以代表所有的结果的可能了,转换成int就是从0到6560,一共也才6561种,计算量并不大。从0到6560遍历一遍看结果是否与输入的值一致,再统计总的一致的次数即可得到答案。

string get_3x(int number)
{
    string symbols = "";
    int remain = 0;
    while(number)
    {
        remain = number % 3;       //取一个十进制数number的对应三进制数的最后一位
        number = number / 3;
        symbols += (remain + ‘0‘);  //数字转字符串
    }
      //string是一个包装了char*的类,有一些方便的函数可以用  int zero_count = 9 - symbols.size();   //不足8位的,高位补0(逆序情况下,在其后补0)
    for(int i =0; i < zero_count; i++)
        symbols += ‘0‘;

    return symbols;
}
// 0 +
// 1 -
// 2 nul
void equation_transfer(int number)
{
    int equal_count = 0;
    const int table_size = 13122;   // 2 * 3^8
    for(int i = 0; i < table_size; i++)
    {
        string symbol = get_3x(i);
        int x = 0;
        int y = 0;
        // cout << symbol << endl;        for(int j = 8; j >= 0; j--)
        {
            if(symbol[j] == ‘0‘)
            {
                x = x + y;
                y = 9 - j;       //y用于保存当前值
            }
            else if(symbol[j] == ‘1‘)
            {
                x = x + y;
                y = -(9-j);
            }
            else
            {
                if(y < 0)
                    y = y * 10 - (9-j);   //当下一个符号为空,将上一个值y与下一个值合并(注意y正负不同,合并方式有差异)
                else
                    y = y * 10 + (9-j);
            }
        }
        if((x+y) == number)
        {
            equal_count++;
            cout << symbol << endl;
        }
    }
    cout << equal_count << endl;
} 

http://blog.csdn.net/u010667082/article/details/47316015

不考虑1之前的符号:

void equation_transfer(int number)
{
    int equal_count = 0;
    const int table_size = 6561;   //  3^8
    for(int i = 0; i < table_size; i++)
    {
        string symbol = get_3x(i);
        int sum = 0;
        int y = 1;
        // cout << symbol << endl;

     string equal_string = "";   //将满足条件的表达式输出     equal_string.clear();
     for(int j = 7; j >= 0; j--)     {       if(symbol[j] == ‘0‘)       {          equal_string += (y + ‘0‘) + ‘+‘;           sum = sum + y;
                y = 9 - j;       //y用于保存当前值
            }
            else if(symbol[j] == ‘1‘)
            {
                equal_string += (y + ‘0‘) + ‘-‘;             x = x + y;
                y = -(9-j);
            }
            else
            {
                if(y < 0)
                    y = y * 10 - (9-j);   //当下一个符号为空,将上一个值y与下一个值合并(注意y正负不同,合并方式有差异)
                else
                    y = y * 10 + (9-j);
            }
        }    //循环结束后,y中保存最后一个数值
        if((sum+y) == number)
        {
            equal_count++;
            cout << symbol << endl;        equal_string += y + ‘0‘;       cout << equal_string << endl;        }
    }
    cout << equal_count << endl;
} 
时间: 2024-10-06 23:20:30

等式变换的相关文章

华为的一道机试题--等式变换

华为的一道机试题 (http://blog.csdn.net/zombie_slicer/article/details/37346025) 第三题:等式变换 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入:       正整数,等式右边的数字 输出:       使该等式成立的个数 样

2015年华为校招机试题和代码实现(分解字符串,拼音转数字,去除重复字符并排序,等式变换)

再来一套2015年的华为机试题. 第一题(60分): 按要求分解字符串,输入两个数M,N:M代表输入的M串字符串,N代表输出的每串字符串的位数,不够补0.例如:输入2,8, "abc" ,"123456789",则输出为"abc00000","12345678","90000000" 分析思路: 容易题 1.获得字符串的长度length后,判断与要输出位数N的大小,大于N的话,直接printf前N位字符,然

[华为机试真题][2014]63.等式变换

题目 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入: 正整数,等式右边的数字 输出: 使该等式成立的个数 样例输入:5 样例输出:21 代码 /*--------------------------------------- * 日期:2015-07-06 * 作者:SJF0115 *

MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术

逻辑查询优化包括的技术 1)子查询优化  2)视图重写  3)等价谓词重写  4)条件简化  5)外连接消除  6)嵌套连接消除  7)连接消除  8)语义优化 9)非SPJ优化 一.子查询优化 1. 什么是子查询:当一个查询是另一个查询的子部分时,称之为子查询. 2. 查询的子部分,包含的情况: a) 目标列位置:子查询如果位于目标列,则只能是标量子查询,否则数据库可能返回类似“错误:子查询只能返回一个字段 ( [Err] 1242 - Subquery returns more than 1

算法实现回顾2——链表环

链表找环最经典的就是快慢指针.而今天的主角也是它了. 快慢指针的思路就是,同时起跑的乌龟和兔子,若赛道无环,则永不相遇,反之则会相遇. 那么我们假定兔子速度是乌龟的2倍. 乌龟和兔子在环中某点相遇,有以下等式:2*x=x+n*k 其中x是乌龟走过的路程,n是兔子绕的圈数,k是圈长. 等式变换 x=n*k,理解就是乌龟走的路程刚好够绕n圈环,而这个路程也是从起点到当前位置的路程. 那么,让另一只乌龟此刻从起点出发,2只乌龟各自继续前进. 根据等式,又会在原先的那点相遇.再想,两者速度相同,那么两者

20170906

水题 T1 Arpa and a research in Mexican wave CodeForces - 851A 1 #include<cstdio> 2 int n,k,t; 3 int main() 4 { 5 scanf("%d%d%d",&n,&k,&t); 6 if(t>=k&&t<=n) 7 printf("%d",k); 8 else if(t<k) 9 printf(&quo

uva 10125和集 sumset(set)

给定数字集合,找出最大的d,使得a+b+c=d且abc均在数字集合中,集合元素数量不超过1000 思路是把等式变换为d-c=a+b,这样只要枚举d,c,验证d-c是否在任意两元素之和所在的集合中,注意abcd不能重复,所以需要一些额外的判重条件 #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<al

条件优化技术

条件: 对元组进行过滤和连接的表达式,形式上是出现在WHERE/JOIN-ON/HAVING的子句中的表达式 1.条件下推 把与单个表相关的条件,放到对单表进行扫描的过程中执行. 2.条件化简 针对:WHERE.HAVING和JOIN-ON条件由许多表达式组成,而这些表达式在某些时候,彼此之间存在一定的联系 (1)having条件并入where条件 不是任何情况下HAVING条件都可以并入WHERE条件,只有在SQL语句中不存在GROUPBY条件或聚集函数的情况下,才能将HAVING条件与WHE

SQL优化--逻辑优化--条件化简

1)查询条件 查询条件概念: SQL查询语句中,对元组进行过滤和连接的表达式,形式上是出现在WHERE/JOIN-ON/HAVING的子句中的表达式. 2)条件化简技术 ①条件下推:把与单个表相关的条件,放到对单表进行扫描的过程中执行. SELECT * FROM A, B WHERE A.a=1 and A.b=B.b; 执行顺序: a)扫描A表,并带有条件A.a=1,把A表作为嵌套循环的外表 b)扫描B表,执行连接操作,并带有过滤条件A.b=B.b 说明:数据库系统都支持条件下推,且无论条件