如此多的循环次数竟然还能过,看来我对运行时间的估计还需要提高提高。
题目概述:
链接: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; }