暴力求解法 之 简单枚举 (一)

2014-11-23 23:21:24 · 作者: · 浏览: 13

1、除法
输入正整数n,按从小到大的顺序输出所有形如abcde / fghij = n的表达式,其中a~j恰好为0~9的一个排列,2<=n<=79.
样例输入:62
样例输出: 79546 / 01283 =62
94736 / 01528 =62
分析: 枚举0~9的所有排列?没这个必要。只需要枚举fghij就可以算出abcde,然后判断是否所有数字都不相同即可。不仅程序简单,而且枚举量也从10!=3628800降低至不到1万。
[cpp]
#include
#include
int main()
{
int i,j,n,s1,s2,flag[10];
while(~scanf("%d",&n))
{
for(i=1234;i<5000;i++)
{
memset(flag,0,sizeof(flag));
/*flag保存每一位数字*/
s1=i;
s2=i*n;
while(s1||s2)
{
if(!flag[s1%10])
{
flag[s1%10]=1;
s1/=10;
}
else
break;
if(!flag[s2%10])
{
flag[s2%10]=1;
s2/=10;
}
else
break;
}
for(j=0;j<10;j++)
if(!flag[j])
break; /*判断是否是10个各不相同的数字*/
if(j==10&&i*n<=98765) /*如果数字各不相同*/
{
if(i<10000) /*除数是一个四位数,有前导0*/
printf("%d / 0%d = %d\n",i*n,i,n);
else
printf("%d / %d = %d\n",i*n,i,n);
}
}
}

#include
#include
int main()
{
int i,j,n,s1,s2,flag[10];
while(~scanf("%d",&n))
{
for(i=1234;i<5000;i++)
{
memset(flag,0,sizeof(flag));
/*flag保存每一位数字*/
s1=i;
s2=i*n;
while(s1||s2)
{
if(!flag[s1%10])
{
flag[s1%10]=1;
s1/=10;
}
else
break;

if(!flag[s2%10])
{
flag[s2%10]=1;
s2/=10;
}
else
break;
}
for(j=0;j<10;j++)
if(!flag[j])
break; /*判断是否是10个各不相同的数字*/
if(j==10&&i*n<=98765) /*如果数字各不相同*/
{
if(i<10000) /*除数是一个四位数,有前导0*/
printf("%d / 0%d = %d\n",i*n,i,n);
else
printf("%d / %d = %d\n",i*n,i,n);
}
}
}
2、最大乘积
输入n个元素组成的序列s,你需要找出一个乘积罪的的连续子序列。如果这个罪的的乘积不是正数,输出-1.1<=n<=18,-10<=Si<=10;
样例输入:
3
2 4 -3
5
2 5 -1 2 -1
样例输出:
8
20
分析:连续子序列有两个要素:起点和终点,因此只需枚举起点和终点即可。由于每个元素的绝对值不超过10,一共又不超过18个元素,最大可能的乘积不会超过10^18,可以用long long 存下。
[cpp]
#include
#include
const int inf=999999;
int main()
{
long long a[20],s[20];
long long i,j,n,max;
while(~scanf("%lld",&n))
{
memset(s,0,sizeof(s));
s[0]=1;
max=-inf;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
s[i]=s[i-1]*a[i];
/*s[i]表示从第一个数到第i个数的乘积*/
}
for(i=1;i<=n;i++) /*子序列长度*/
{
for(j=i;j<=n;j++)
{
if(s[j]/s[j-i]>max)
max=s[j]/s[j-i];
}
}
if(max<0)
max=-1;
printf("%lld\n",max);
}
return 0;
}

#include
#include
const int inf=999999;
int main()
{
long long a[20],s[20];
long long i,j,n