`
Simone_chou
  • 浏览: 185108 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Prime Cryptarithm(枚举)

 
阅读更多
Prime Cryptarithm

The following cryptarithm is a multiplication problem that can be solved by substituting digits from a specified set of N digits into the positions marked with *. If the set of prime digits {2,3,5,7} is selected, the cryptarithm is called a PRIME CRYPTARITHM.

      * * *
   x    * *
    -------
      * * *         <-- partial product 1
    * * *           <-- partial product 2
    -------
    * * * *

Digits can appear only in places marked by `*'. Of course, leading zeroes are not allowed.

Note that the 'partial products' are as taught in USA schools. The first partial product is the product of the final digit of the second number and the top number. The second partial product is the product of the first digit of the second number and the top number.

Write a program that will find all solutions to the cryptarithm above for any subset of digits from the set {1,2,3,4,5,6,7,8,9}.

PROGRAM NAME: crypt1

INPUT FORMAT

Line 1: N, the number of digits that will be used
Line 2: N space separated digits with which to solve the cryptarithm

SAMPLE INPUT (file crypt1.in)

5
2 3 4 6 8

OUTPUT FORMAT

A single line with the total number of unique solutions. Here is the single solution for the sample input:

      2 2 2
    x   2 2
     ------
      4 4 4
    4 4 4
  ---------
    4 8 8 4

SAMPLE OUTPUT (file crypt1.out)

1

   题意:

   有N个数,使这N个数满足以上的乘法法则,并且乘出来的每个数都在给出的这N个数中。

 

   思路:

   在已给出的数中一个个列举出来再乘起来判断,满足条件则sum积累。

 

   AC:

 

/*
TASK:crypt1
LANG:C++
ID:sum-g1
*/
#include<stdio.h>
#include<stdlib.h>
int number[15];
int n;

int test(int a,int b)
{
	int k,temp=0;
	while(a)
	{
		for(k=0;k<n;k++)
		 if((a%10)==number[k]) {temp++;break;}
		a/=10;
	}
	if(temp==b)  return 1;
	else         return 0;
}
//test用来测试乘起来的这些数是否在已给出的数中
//a代表这个数,b代表位数
int main()
{
freopen("crypt1.in","r",stdin);
freopen("crypt1.out","w",stdout);	
int i,first,second;
	int t1,t2,t3,t4,t5;
	int sum=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&number[i]);
	for(t1=0;t1<n;t1++)
	{
		for(t2=0;t2<n;t2++) 
//一开始手抽写成t2<0,导致循环不能进行,要细心!
		{
			for(t3=0;t3<n;t3++)
			{
				first=number[t1]*100+number[t2]*10+number[t3];
//列举这三位数,使它变成一个整数,非一个个字符
				for(t4=0;t4<n;t4++)
				{
					if(number[t4]*first>999) continue;
					if(!test(number[t4]*first,3)) continue;
					for(t5=0;t5<n;t5++)
					{
					second=number[t4]*10+number[t5];
//列举这两位数,使它变成一个整数,非一个个字符
					if(number[t5]*first>999) continue;
//超过3位数在排除
					if(!test(number[t5]*first,3)) continue;
//不是已给出的数则排除
					if(second*first>9999||!test(second*first,4)) continue;
//乘出来的数不是4位数,或者这个4位数不是已给出的数
					if(second*first<9999&&second*first>1000&&test(second*first,4))  sum++;
//是4位数,且是给出的数,则sum积累
					}
				}
			}
		}
	}
	printf("%d\n",sum);
	exit(0);
}

   更优化的办法:

   换种角度思考来列举,既然已经规定第一个数为3位数,第二个数为2位数,则三位数 i 从100列举到999,二位数 j 从10到99。仅仅只需要两重循环,并且满足条件即可:

   1.判断这个数是否由已给出的数所组成;

   2.判断这个两位数个位和十位分别与 这个满足条件1的三位数 i 相乘是否都是三位数,并且是否满足1条件;

   3.满足1和2条件下,将i与j相乘,得出的数result是否为一个4位数,并且是否满足条件1。

   下面的技巧在于用数组0,1标记这个数是否存在。

/*
TASK:crypt1
LANG:C++
ID:sum-g1
*/
#include<stdio.h>
int hash[15]={0};
int n;

int test(int a)
{
	while(a)
	{
	 if(!hash[a%10]) return 0;  
//记得要%10 
	 a/=10;
    }
    return 1;
}

int main()
{
freopen("crypt1.in","r",stdin);
freopen("crypt1.out","w",stdout);	
int number,i,j;
	int first,second,sum=0,result;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&number);
		hash[number]=1;
	}	
	for(i=100;i<1000;i++)
	{
		if(!test(i)) continue;
		for(j=10;j<100;j++)
		{
			if(!test(j)) continue;
			first=(j%10)*i;
			second=(j/10)*i;
			if(first<100||first>999||second>999||second<100)   continue;
			if(!test(first)||!test(second)) continue;
			result=i*j;
			if(!test(result)||result>9999||result<1000)  continue;
			sum++;
		}
	}
	printf("%d\n",sum);
}

   总结:

   当题目的条件比较多时,应一一列举出来,细心分析归纳,理清好思路非常重要。题目看起来好像很麻烦的样子,但是仔细分析的话其实也只是多了几个条件而已,数据看起来很庞大,但是当写完出来之后发现也只不过是这样而已。有时候做题往往就是被这种表面的东西吓到了,所以不愿去尝试,必须去习惯做这类枚举的题目,尝试总比什么都不做要好。

分享到:
评论

相关推荐

    USACO官网93题fps格式 OJ题库

    USACO 官网第一到 五章 练习题中文语言官方数据 fps格式支持导入所有OJ 1 [1.1] 你的飞碟在这儿 Your Ride Is Here...12 [1.3] 牛式 Prime Cryptarithm 13 [1.3] 虫洞 wormhole 14 [1.3] 滑雪课程设计Ski Course Design

    E-Prime程序示例.zip

    E-Prime示例集E-Prime示例集E-Prime示例集E-Prime示例集E-Prime示例集E-Prime是由卡奈基-梅龙大学和匹兹堡大学联合开发心理学实验操作平台,是一个高等的图形设计环境,提供革命性的新工具,以加速实验发展,E-Prime...

    prime 算法 prime

    prime 算法 prime prime prime

    LynX_Prime_Interface.rar_lynx prime_lynx vega_vega_vega prime_ve

    vega prime 使用模块说明vega prime 使用模块说明vega prime 使用模块说明

    eprime真正破解版1.1

    心理学实验eprime

    E-Prime音频控件使用简单测试

    用于E-Prime的初学者解决一些音频控件相关的简单设置问题,是E-Prime 2.0版本软件创建的一个非常简单的项目示例。

    vega prime安装步骤

    用于vega prime的安装,可以使读者能够准确并且轻松地完成安装

    prime95使用教程.pdf

    prime95使用教程.pdfprime95使用教程.pdfprime95使用教程.pdfprime95使用教程.pdfprime95使用教程.pdfprime95使用教程.pdf

    primesense Sensor-Win64-5.1.6.6

    primesense Sensor-Win64-5.1.6.6,用于windows系统32位primesense sensor的驱动

    E-prime真正破解版

    用于心理实验的E-prime程序,希望帮助到大家。

    IAT实验E-PRIME报告.doc

    IAT实验E-PRIME报告

    心理学eprime制作flanker实验

    心理学eprime制作flanker实验

    E-Prime软件+安装方法+教程

    E-Prime软件+安装方法+教程 毕设的时候用的,总结上传上来,完全可以使用。

    HP Prime 绘图计算器

    HP prime 计算器的手册。 HP Prime 绘图计算器是一款易于使用且功能强大的绘图计算器,它是专为中学及高等数学教育而设计 的。它提供了数百个函数和命令,并且包含一个用于符号计算的计算机代数系统 (CAS)。 除了...

    Quartus Prime 18.1 破解器

    Quartus Prime 18.1 破解器 # 第一步: 把Quartus_18.1破解器.exe复制到C:\intelFPGA\18.1\quartus\bin64和/或C:\intelFPGA_Pro\18.1\quartus\bin64下运行(你的安装目录也许和这个不一样),也就是说把它和quartus....

    E-prime实验设计技术(曾祥炎)

    E-prime实验设计技术

    Prime OS_mainline_v0.4.5.iso

    Android x86 系列的操作系统,在PC上运行的安卓, 非虚拟机模拟。 PrimeOS_Mainline_v0.4.5 , ISO 安装盘映像文件。网盘下载链接。

    PrimeOS_Mainline_v0.4.5_Windows x64 安装包

    Android x86 系列的操作系统,在PC上运行的安卓, 非虚拟机模拟。 PrimeOS_Mainline_v0.4.5 , Windows x64 安装包。网盘下载链接。

    stroop程序eprime演示

    心理学程序软件eprime的演示程序,是经典stroop效应的演示

    Prime95中文版

    Prime95是一款专门测试系统稳定的软件,在所有的烤机软件中,Prime95 是公认的最残酷的一款.它把负荷高得有点离谱的工作量加载在CPU身 上,以此来考验CPU的承受能力.这一测试因其可以发现其他测试程序无法发现的稳定性...

Global site tag (gtag.js) - Google Analytics