现在的位置: 首页 > 综合 > 正文

USACO 1.3.3 Prime Cryptarithm

2017年10月16日 ⁄ 综合 ⁄ 共 1107字 ⁄ 字号 评论关闭

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

题目概述:

链接: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;
}

抱歉!评论已关闭.