USACO 1.3.3 Prime Cryptarithm

来源:互联网 发布:数据库中create table 编辑:程序博客网 时间:2024/05/17 15:03

如此多的循环次数竟然还能过,看来我对运行时间的估计还需要提高提高。


题目概述:

链接:http://cerberus.delosent.com:791/usacoprob2?a=4eAR5fGw7OX&S=crypt1

嗯这道题是说我们要从给定集合里面做一个竖式乘法,是一个三位数乘以两位数。这个竖式乘法中出现的所有数(包括乘数,中间步骤出现的数)都要满足在这个集合里面,并且要求中间步骤的数字是三位,最后结果是四位。

算法思想:

我当时的第一想法真真心就是五重循环,但是同时也有一丝担忧觉得这样时间上实在是太慢了,但是因为想不出别的东西就硬着头皮写。

第一遍写完之后发现题目读错了,没有看到那个所有数都要在这个集合里面出现,所以就开了新的布尔数组b去记录这个数字到底有没有出现过。

然后中间步骤新开一个函数检验了一下,这题也就水水过去了。

代码部分:

#include <iostream>#include <list>#include <map>#include <math.h>#include <string.h>#include <string>#include <fstream>#include <algorithm>using namespace std;ifstream fin("crypt1.in");ofstream fout("crypt1.out");int n;int a[11];bool b[11] = { 0 };bool check(int p) {while (p != 0) {if (!b[p % 10]) return false;p /= 10;}return true;}int main() {fin >> n;for (int i = 0; i < n; i++) {fin >> a[i];b[a[i]] = 1;}int res = 0;for (int i1 = 0; i1 < n; i1++) {for (int i2 = 0; i2 < n; i2++) {for (int i3 = 0; i3 < n; i3++) {for (int i4 = 0; i4 < n; i4++) {for (int i5 = 0; i5 < n; i5++) {int abc = a[i1] * 100 + a[i2] * 10 + a[i3];int p1 = a[i5] * abc;if (p1 < 100 || p1>999) continue; // 如果中间不是三位就舍弃int p2 = (a[i4] * abc);if (p2 < 100 || p2>999) continue; // 同上,如果中间不是三位就舍弃if (check(p1) && check(p2)) {int p = p1 + 10 * p2;if (p >= 1000 && p <= 9999 && check(p)) {res++;}}}}}}}fout << res << endl;return 0;}


0 0
原创粉丝点击