USACO1.3牛式 Prime Cryptarithm

戳我看题面

题目描述

下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式。

      ***
x     **

     ***
    ***

    ****

(请复制到记事本)

数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0。

注意一下在美国的学校中教的“部分乘积”,第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积.

写一个程序找出所有的牛式。

输入输出格式

输入格式:
Line 1:数字的个数n。

Line 2:N个用空格分开的数字(每个数字都属于{1,2,3,4,5,6,7,8,9})。

输出格式:
共一行,一个数字。表示牛式的总数。

输入输出样例

输入样例#1: 复制
5
2 3 4 6 8
输出样例#1: 复制
1
说明

题目翻译来自NOCOW。

USACO Training Section 1.3

首先我的具体思路是枚举,就枚两个数,一个枚十位,一个枚百位.这里和楼下用枚举的dalao一毛一样.

然后再输入时弄一个桶,把所有的数字存起来,再枚举时一一算出牛式的每个式子—–
         ***
    x     **
   ----------
         ***
        ***
   ----------
        ****

就是把上面每一个由*组成的式子算出来,最后再一一判断每一位即可

具体上代码

/*
ID: czj20052
LANG: C++
TASK: crypt1
*///别在意,USACO上要的
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int a[10];//一个桶,代表输入了那些数字,由于最大只能到9所以只要开10
int ss(int i,int j)//判断是否为牛式的函数,0代表不是,1代表是
{
    int a1=i*(j%10);
    int b=i*(j/10);
    int c=i*j;
    if(a1>999) return 0;
    if(b>999) return 0;
    if(c>9999) return 0;//注意这三行!!!如果不判断的话就会多出原本不要的式子了!!!
    while(i!=0)
    {
        if(a[i%10]==0)
        {
            return 0;
        }
        i/=10;
    }
    while(j!=0)
    {
        if(a[j%10]==0)  return 0;j/=10;}
    while(a1!=0)
    {
        if(a[a1%10]==0) return 0;a1/=10;
    }
    while(b!=0)
    {
        if(a[b%10]==0) return 0;b/=10;
    }
    while(c!=0)
    {
        if(a[c%10]==0) return 0;c/=10;
    }//这几个while循环就是判断每一位是否在桶子里
    return 1;
}
int main()
{
    freopen("crypt1.in","r",stdin);
    freopen("crypt1.out","w",stdout);
    int n,x;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        a[x]++;//输入,进桶
    }
    int s1=0;
    for(int i=100;i<=999;i++)
    {
        for(int j=10;j<=99;j++)
        {
            if((i*j)>9999)
            {
                continue;
            }
            if(ss(i,j)==1)
             {
                 s1++;
             }
        }//枚举所有的三位数和二位数,如果是,计数器加一
    }
    cout<<s1<<endl;//输出
    return 0;
}
这里写代码片

最后,让我们膜拜一下桶吧!! !

music 我才不会告诉你复制时要把freopen注释掉呢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值