回 帖 发 新 帖 刷新版面

主题:第70次编程比赛题目

[size=3]上次比赛冠军得主因为长时间没有再在此发帖子,也联系不到
正好偶有题目,先抢占个位置了。。。

本次比赛题目如下:

[color=Blue]题目描述:[/color]
有n个正整数(4<=n<=13),在这n个正整数之间插入四则运算符,
使得结果恰好等于一个给定的整数值,注意这n个整数的先后顺序不能改变,
不插入运算符的地方的数字直接连起来成一个新数,
如1 2之间不插入运算符则为12,1 2 3之间的话则为整数123
如:1*23-4=19  12+3+4=19

[color=Blue]输入:[/color]
你的程序只需处理一组测试数据,每组第一行1个正整数n
接下来一行为n个小于20的正整数,这n个数和结果连起来总长度小于15位
第三行为要计算出的结果k(-10000<k<10000)

[color=Blue]输出:[/color]
输出1行1个整数,表示解的个数

[color=Blue]样例输入:[/color]
4
1 2 3 4
2

[color=Blue]样例输出:[/color]
2

[color=Blue]其它信息:[/color]
对于样例,只有
1+2+3-4 = 2
1*2*3-4 = 2
两组解
注意 -1+2-3+4=2 这组不合法,只能为四则运算符,不能作为正负号
[color=Red]你需要考虑运算优先级[/color]
题目来源:yzfy无聊改编


比赛结束时间:8月18日 23:00
比赛代码提交方式:直接回复本帖子,回复将隐藏
主要评比内容:代码时间效率
比赛注意事项:必须严格按照要求进行输入输出,不要输出多余的内容
其它:本题提供在线测试,链接[url]http://yzfy.org/dis/listpost.php?tid=897[/url]
如有疑问,请到[url]http://bbs.pfan.cn/post-282271.html[/url]提出
[/size]

回复列表 (共34个回复)

11 楼


看看,[em18][em19]

12 楼

新手 学习学习

13 楼

我的想法是一个递归,一个穷举函数.

递归是从4个数3个..到一个数不同的序列,收穷举法计算出是否符合题目要求.

14 楼

对不起 今天有事晚上10点多才回来 没有把程序写好..想了半个钟头没想到什么好办法没想到辜负了我上午占的位子..[em26][em52]

15 楼

#pragma warning(disable: 4786)
#include <iostream> 
#include <string> 
#include <stack> 
#include <vector> 
#include<cmath>
using namespace std;
int Compare(char op) //优先级比较
{
    int Level = 0; 
    switch(op) 
    { 
        case '+':case '-': 
        Level = 1; 
        break; 
        case '*':case '/': 
        Level = 2; 
        break;  
        case '#': 
        Level = 3; 
        break;  
        default: 
        break; 
    } 
    return Level;
}
void RPN(string expression,const vector<int> ivec,vector<string> &sResult,int n)  //产生后缀表达式

    int index = 0; 
    stack<char> stmp; 
    bool flag = false; 
    stmp.push('@'); //运算符堆栈的栈底元素
    int i=0;
    char *temp=new char();
    string cs;
    while( index<(n-1)) 
    {
        
        cs=itoa(ivec[i],temp,10);//将int型数据转化为string
        sResult.push_back(cs); 
        i++;
        while( Compare( expression[index] ) <= Compare( stmp.top() )) 
            //比较优先级,如果此时的运算符优先级小于等于栈顶元素,则栈顶运算符出栈.
        { 
            sResult.push_back(string(1, stmp.top()) ); 
            stmp.pop(); 
        } 
        stmp.push( expression[index] ); 
        index++;  
    }//while 

    cs=itoa(ivec[i],temp,10);
    sResult.push_back(cs); 
    while(stmp.top()!='@')
    {
        sResult.push_back(string(1, stmp.top()) ); 
        stmp.pop(); 
    }
}//RPN 

16 楼

double Clculate(vector<string> &sResult) //后缀表达式计算结果

    stack<double> snum; 
    size_t index = 0; 
    double num1 = 0, num2 = 0; 
    for(index = 0; index < sResult.size(); ++index) 
    { 
        string oper = sResult[index]; 
        switch(oper[0]) 
        { 
            case '+': //运算符为+
            { 
                num1 = snum.top(); 
                snum.pop(); 
                num2 = snum.top(); 
                snum.pop(); 
                snum.push( num2 + num1); 
            } 
            break; 
            case '-': //运算符为-
            { 
                num1 = snum.top(); 
                snum.pop(); 
                num2 = snum.top(); 
                snum.pop(); 
                snum.push( num2 - num1); 
            } 
            break; 
            case '*': //运算符为*
            { 
                num1 = snum.top(); 
                snum.pop(); 
                num2 = snum.top(); 
                snum.pop(); 
                snum.push( num2 * num1); 

            } 
            break; 
            case '/': //运算符为/
            { 
                num1 = snum.top();  
                snum.pop(); 
                num2 = snum.top(); 
                snum.pop(); 
                if(num1 == 0) //如果分母为0,则返回一个无用的数
                { 
                    cerr << "Expression worng!" << endl; 
                    return 10000;
                } 
                snum.push( num2 / num1); 
            } 
            break; 
            case '#': //#号表示两数字之间没有符号,则须把这两个数合在一起看成一个数
            { 
                num1 = snum.top(); 
                snum.pop(); 
                num2 = snum.top(); 
                snum.pop(); 
                int i=num1;
                int no=10;
                while(i=i/10>0) //如果处在#运算符右边的数为2位,则左边的数要乘上100再加上右边的数
                {
                    no*=10;
                }
                snum.push( num2*no + num1); 
            } 
            break; 
            default: 
            { 
                snum.push( atoi(sResult[index].c_str()) ); //把数字压入栈中
            } 
            break; 
        }//swith 
        
    }//while 

    double result = snum.top(); 
    snum.pop(); 
    return result; 
}

17 楼

int main() 

    
    string Input; //Input用于存贮运算符+-*/#,其中#表示没有运算符 
    int i,n,m,T=0,T2;
    int approve=0;
    int word_size=0;
    int approv=0;
    double k;
    vector<int> ivec;
    vector<string> result;
//    cout << "please input a number (4=<n<=13):" <<endl;
    cin>>n;
    while(n>13||n<4)
    {
        cout<<"请输入4=<n<=13之间的数"<<endl;
        cin>>n;
    }
//    cout << "please input those n data (n):" <<endl;
    for(i=0;i<n;i++)
    {
       cin>>m;
      ivec.push_back(m); 
    }
    for(i=0;i<ivec.size();i++)
    {
        word_size++;
        if(ivec[i]>=10) word_size++;    
    }
//    cout << "please input the result (-10000<k<10000):" <<endl;
    cin>>k;
    while(k>=10000||k<=-10000)
    {
        cout<<"请输入-10000<k<10000之间的数"<<endl;
        cin>>k;
    }
    int sum=pow((double)5,(double)(n-1));
    while(T<sum)
    {
        T2=T;
        int oper=0;  
        for(int i=0;i<n-1;i++)
        {
            oper++;
            m=T2%5;
            if(m==0) Input=Input+"+"; 
            else if(m==1) Input=Input+"-";
            else if(m==2) Input=Input+"*";
            else if(m==3) Input=Input+"/";
            else  {Input=Input+"#";oper--;}
            T2=T2/5;
        }
        T++;
        if((word_size+oper)>=15) continue;//n个数和结果连起来总长度小于15位
        RPN(Input,ivec,result,n); 
        double kval=Clculate(result); 
        if(kval==k)
        {
        /*    cout << "表达式:" <<endl; 
            for(size_t index = 0; index < Input.size(); ++index) 
            { 
                cout<<ivec[index];
                if(Input[index]!='#')
                {        
                    cout << Input[index]; 
                }    

            } 
            cout<<ivec[ivec.size()-1];
            cout<<"="<<kval<<endl;     //这一段显示运算表达式*/
            approv++;
        }
        result.clear();
        Input="";
    }
    cout<<approv<<endl;
    return 0; 

18 楼


#include<stdio.h>

int count(int i,int sum,int last)
{
 int current=p[i+1];
 if(i==length)
   return (sum+last==k);
 else
   return
   count(i+1,sum+last,current)
  +count(i+1,sum-last,current)
  +count(i+1,sum,last*10+current)
  +count(i+1,sum,last*current)
  +count(i+1,sum,last/current)
  -((last%current!=0)||(current==0));
}

 int result(int n)
  {
   length=n;
    return count(1,0,p[1]);
  }

int main()
{
  int n,i,sum,last,current,k,length,answer;
  scanf("%d\n",&n);
  for(i=0;i<n;i++){
    scanf("%d ",&p[i]);
  }
  scanf("%d",&k);
  answer=result(n);
 return answer;
}

19 楼

晕,好像有个语法错误!给这个板块丢脸了···

20 楼

我想看看大家的想法!

我来回复

您尚未登录,请登录后再回复。点此登录或注册