USACO section 1.3.4 Prime Cryptarithm

1. 枚举,注意里边的几个剪枝,标在代码中了

2. 我的代码:

/*
ID: dollar4
PROG: crypt1
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;
int num[10], n;
bool cmp(int a, int b)
{
    return a < b;
}
bool findin(int a)
{
    for (int i = 0; i < n; i++)
        if (num[i] == a)
            return true;
    return false;
}

int main()
{
    ofstream fout ("crypt1.out");
    ifstream fin ("crypt1.in");
    fin >> n;
    int i, j, k, l, m, s1, s2, s3, s4, s5;
    int cnt = 0, mm, nn, mn;
    for (i = 0; i < n; i++)
        fin >> num[i];
    sort(num, num + n, cmp);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            for (k = 0; k < n; k++)
                for (l = 0; l < n; l++)
                    for (m = 0; m < n; m++)
                    {
                        s1 = num[i];
                        s2 = num[j];
                        s3 = num[k];
                        s4 = num[l];
                        s5 = num[m];
                        mm = s4 * (s1 * 100 + s2 * 10 + s3);
                        nn = s5 * (s1 * 100 + s2 * 10 + s3);
                        mn = nn + 10 * mm;
                        if (s1 * s4 > 9 || s5 * s1 > 9)//相乘必须是3位数
                            continue;
                        //想加的约束
                        if (s1 * s4 + s2 * s4 / 10 >= 10 || s1 * s5 + s2 * s5 / 10 >= 10)//nn / 100 + mm % 100 / 10 < 10 ||
                            continue;
                        //运算得到的结果有没有超出所给的数组之外的
                        if ( !findin(nn / 100) || !findin(nn % 100 / 10) || !findin(nn % 10) || !findin(mm / 100) || !findin(mm % 100 / 10) || !findin(mm % 10))
                            continue;
                        if (!findin(mn / 1000) || !findin(mn % 1000 / 100) || !findin(mn % 100 / 10) || !findin(mn % 10))
                            continue;
                        cnt++;
                    }
    fout << cnt << endl;
    return 0;
}


 
  
2. 官方代码:

The constraints of this problem are small enough that we can just try all possible products of 3 digit * 2 digit numbers, and look to see if all the correct digits are used.

The function "isgood" checks that a number is composed only of acceptable digits, and "isgoodprod" checks that all the lines of the multiplication are composed of acceptable digits.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

int isgooddigit[10];	/* isgooddigit[d] is set if d is an acceptable digit
*/

/* check that every decimal digit in "n" is a good digit,
   and that it has the right number "d" of digits. */
int
isgood(int n, int d)
{
    if(n == 0)
		return 0;

    while(n) {
	if(!isgooddigit[n%10])
	    return 0;
	n /= 10;
        d--;
    }

    if( d == 0 )
       return 1;
    else
       return 0;
}

/* check that every product line in n * m is an okay number */
int
isgoodprod(int n, int m)
{
    if(!isgood(n,3) || !isgood(m,2) || !isgood(n*m,4))
	return 0;

    while(m) {
	if(!isgood(n*(m%10),3))
	    return 0;
	m /= 10;
    }
    return 1;
}

void
main(void)
{
    int i, j, n, nfound;
    FILE *fin, *fout;

    fin = fopen("crypt1.in", "r");
    fout = fopen("crypt1.out", "w");
    assert(fin != NULL && fout != NULL);

    for(i=0; i<10; i++) {
        isgooddigit[i] = 0;
    }
    fscanf(fin, "%d", &n);
    for(i=0; i<n; i++) {
	fscanf(fin, "%d", &j);
	isgooddigit[j] = 1;
    }

   nfound = 0;
   for(i=100; i<1000; i++)
	for(j=10; j<100; j++)
	    if(isgoodprod(i, j))
		nfound++;

   fprintf(fout, "%d\n", nfound);
   exit(0);
}




你可能感兴趣的:(USACO)