主题:第70次编程比赛题目
雨中飞燕 [专家分:18980] 发布于 2008-08-08 19:21:00
[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]
最后更新于:2008-08-12 12:11:00
回复列表 (共34个回复)
11 楼
jinghua1600 [专家分:0] 发布于 2008-08-14 11:29:00
看看,[em18][em19]
12 楼
swj2_0 [专家分:0] 发布于 2008-08-15 13:24:00
新手 学习学习
13 楼
xihai [专家分:0] 发布于 2008-08-15 22:45:00
我的想法是一个递归,一个穷举函数.
递归是从4个数3个..到一个数不同的序列,收穷举法计算出是否符合题目要求.
14 楼
hyqhero [专家分:50] 发布于 2008-08-17 13:47:00
对不起 今天有事晚上10点多才回来 没有把程序写好..想了半个钟头没想到什么好办法没想到辜负了我上午占的位子..[em26][em52]
15 楼
apart789 [专家分:640] 发布于 2008-08-17 18:42:00
#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 楼
apart789 [专家分:640] 发布于 2008-08-17 18:43:00
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 楼
apart789 [专家分:640] 发布于 2008-08-17 18:43:00
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 楼
JackieRasy [专家分:3050] 发布于 2008-08-18 13:22:00
#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 楼
JackieRasy [专家分:3050] 发布于 2008-08-18 13:23:00
晕,好像有个语法错误!给这个板块丢脸了···
20 楼
kane_0313 [专家分:0] 发布于 2008-08-18 15:12:00
我想看看大家的想法!
我来回复