除法(Division,uva725)
输入整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列(可以有前导0),2<=n<=79。
输入:输入若干组数据,以文件结束符结束。
输出:For each test case you must print the message: Case #M: The maximum product is P., where M is the number of the test case, starting from 1, and P is the value of the maximum product. After each test case you must print a blank line.
样例输入:
62
样例输出:
79546/01283=62
94736/01528=62
方法1:利用3重循环枚举起点和终点。
错误程序:
#include<iostream>
#include<cstdio>
using namespace std;
int a[30];
int main(){
int n,m=0;
while (cin>>n){
m++;
long long maxc=0,s;
for(int i=1;i<=n;i++) cin>>a[i];
for (int i=1;i<=n;i++){
for (int j=i+1;j<=n;j++){//程序错误:考虑不全,当单个数为最大值时,(更没有考虑到,当第n个数为最大值的情况),不能出正确结果
s=a[i];
for (int k=i+1;k<=j;k++)s=s*a[k];
if (s>maxc) maxc=s;
}
}
cout<<"Case #"<<m<<": The maximum product is "<<maxc<<"."<<endl<<endl;
}
return 0;
}
修改1:
for (int i=1;i<=n;i++){
for (int j=i;j<=n;j++){
s=a[i];
if (s>maxc) maxc=s;
for (int k=i+1;k<=j;k++)s=s*a[k];
if (s>maxc) maxc=s;
}
}
继续修改:
for (int i=1;i<=n;i++){
for (int j=i;j<=n;j++){
s=1;
for (int k=i;k<=j;k++)s=s*a[k];
if (s>maxc) maxc=s;
}
}
简化:由三重循环修改为二重
for (int i=1;i<=n;i++){
s=1;
for (int j=i;j<=n;j++){
s=s*a[j];//累乘即可
if (s>maxc) maxc=s;
}
}
继续简化:能不能用一维实现
思路,动态规划,模拟加法的最长连续子序列 f[i]=max(f[i-1],a[i]),则有:
因为本题是乘法,需要如果只单纯记录最大值是不妥当的,因为负数的最小值*负数结果也可能最大。所以有:
f[i]=max(max(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
g[i]=min(min(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[30],g[30],a[30];
int main(){
int n,m=0;
while (cin>>n){
m++;
long long maxc=0,s;
for(int i=1;i<=n;i++) cin>>a[i];
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
for (int i=1;i<=n;i++){
f[i]=max(max(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
g[i]=min(min(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
}
for(int i=1;i<=n;i++)if (maxc<f[i]) maxc=f[i];
cout<<"Case #"<<m<<": The maximum product is "<<maxc<<"."<<endl<<endl;
}
return 0;
}
符:算法竞赛入门经典例题7—2