简单枚举(UVA725、UVA11057、UVA10976)

本文深入探讨了编程中枚举技巧的应用,从UVA平台上的具体问题出发,详细解析了解题思路和关键点。包括如何通过枚举简化问题、避免重复计算、优化算法效率等。同时,提供了代码实现和注意事项,帮助读者掌握从简单到复杂问题的编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我闲着无聊写了几题简单的枚举,然后发现我对编程细节的控制有点差,以后还是要写写一些简单的题目难过


一、UVA725 Division

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35442

题目大意:输入正整数n,将其表示成abcde/fghij=n的形式,且a~j是数字0~9的一个排列


分析:

首先,枚举0~9是肯定不行的,所以该怎么暴力枚举呢?

其实,只要枚举fghij就可以通过乘上n得到abcde,然后再判断是否可行

且当fghij>10^6时就可以跳出枚举了,

所以,枚举也要动脑子。


注意:1、可以用数组来标记该数字是否已使用过,但在循环结束时要将标记清零。

          2、枚举时注意剪枝。

          3、输出“There are no solutions for n."时有一个WA了我2次的句号,虽然我知道各位肯定不会出错,但我还                 是想提醒一下你们。

          4、每一组输出数据之间有空行,但最后一行没有空行。


下面附上代码:

#include<cstdio>
#include<cstring>

int n,a[10],kase=0;

int main()
{
  while(scanf("%d",&n)&&n)
  {
  	if(kase++)printf("\n");
  	bool f=true,ok=false;
  	memset(a,1,sizeof(a));//通过 a数组标记来看数字是否已使用过 
  	for(int i1=0;i1<=99999/n/10000;i1++)
  	{
  	  a[i1]=0;
  	  for(int i2=0;i2<=9;i2++)
  	  if(a[i2])
  	  {
  	    a[i2]=0;
  	    for(int i3=0;i3<=9;i3++)
  	    if(a[i3])
  	    {
  	      a[i3]=0;
  	      for(int i4=0;i4<=9;i4++)
  	      if(a[i4])
  	      {
  	        a[i4]=0;
  	        for(int i5=0;i5<=9;i5++)
  	          if(a[i5])
  	          {
  	          	a[i5]=0;
  	          	
  	          	int x=n*(i1*10000+i2*1000+i3*100+i4*10+i5);
  	          	
  	          	if(x>=100000){ok=true;break;}//当abcde和fghij加起来超过10位时可以终止枚举 
  	          	
  	          	int b1=x/10000,b2=x/1000%10,b3=x/100%10,b4=x/10%10,b5=x%10;
  	          	
  	          	if(a[b1]){
  	          	  a[b1]=0;
  	          	  if(a[b2]){
  	          	  	a[b2]=0;
  	          	  	if(a[b3]){
  	          	  	  a[b3]=0;
  	          	  	  if(a[b4]){
  	          	  	  	a[b4]=0;
  	          	  	  	if(a[b5])
  	          	  	  	{
  	          	  	  	  printf("%d%d%d%d%d / %d%d%d%d%d = %d\n",b1,b2,b3,b4,b5,i1,i2,i3,i4,i5,n);
  	          	          f=false;//说明n可以分解 
                        }
                        a[b4]=1;//每次别忘了将值变回1 
					  }
					  a[b3]=1;
					}
					a[b2]=1;
				  }
				  a[b1]=1;
  	            }
  	            a[i5]=1;
			  }
  	        if(ok)break;
  	        a[i4]=1;
  	      }
  	      if(ok)break;
  	      a[i3]=1;
  	    }
  	    if(ok)break;
  	    a[i2]=1;
      }
      if(ok)break;
      a[i1]=1;
    }
  	if(f)printf("There are no solutions for %d.\n",n);//注意输出时有一个“.”。 
  }
  return 0;
}



二、UVA11059 Maximum Product

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27946

题目大意:给n个数,找出乘积最大的连续子序列。


分析:

由于数据范围小到爆了,直接枚举起点和终点。


注意:1、在记录乘积和答案是,要使用long long。

          2、记录数列的数组s要开的大一点(你们知道,UVA给的数据范围向来是不靠谱的,我就因为没有开大点WA                了3次,不信的话你自己用s[18]来试试)。

          3、一定要好好读题,看看有没有没有注意到的细节。


下面是代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int n,s[20],kase=0;//一定要将s定义大一点,不然总是WA 

int main()
{
  while(scanf("%d",&n)!=EOF)
  {
  	long long ans=0;
  	for(int i=1;i<=n;i++)scanf("%d",&s[i]);
  	for(int i=1;i<=n;i++)//直接枚举序首 
  	{
	  long long x=1;
	  for(int j=i;j<=n;j++)
	  {
	  	x*=s[j];
	  	if(x>ans)ans=x;
	  }
    }
    printf("Case #%d: The maximum product is %lld.\n\n",++kase,ans);
  }
  return 0;
}

三、UVA10976 Fractions Again

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=37234

我太懒了,所以这题你们自己练习吧。


但无论如何,————注意细节


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值