UVA 10396 - Vampire Numbers(暴力打表)

Problem D

Vampire Numbers

Input: standard input

Output: standard output

Time Limit: 5 seconds

 

A number v = xy with an even number (n) of digits formed by multiplying a pair of n/2-digit numbers (where the digits are taken from the original number in any order) x and y together is known as vampire number. Pairs of trailing zeros (Both the numbers have a trailing zero) are not allowed. If v is a vampire number then x and y are called its "fangs." Examples of 4-digit vampire numbers include

 

1) 21 x 60 = 1260
2) 15 x 93 = 1395
3) 35 x 41 = 1435
4) 30 x 51 = 1530
5) 21 x 87 = 1827
6) 27 x 81 = 2187
7) 80 x 86 = 6880

 

In this program you will have to find all the 46 and 8 digit even vampire numbers.

 

Input

The input file contains maximum ten lines of input. Each line contains a single integer n whose value is 46 or 8. Input is terminated by end of file.

 

Output

For each input n produce all the n-digit vampire numbers that are even in ascending order. Print a blank line after the output for each set of input.

 

Sample Input:

4

4

 

Sample Output:

1260

1530

6880

 

1260

1530

6880

题意:输出所有吸血鬼偶数,满足条件为分成n/2的两位数相乘等于本身,并且两个数不能同时尾随0.

思路:暴力枚举,每一个都去判断,如果是两个奇数相乘必然为奇数直接continue,答案全放入set里面,自动排序去重,最后输出,这样跑了7秒。但是n其实只有4,6,8.每一次求出来的答案保留下来,下次继续用,优化到2秒多。

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <set>
using namespace std;

const int ten[5] = {1, 10, 100, 1000, 10000};
int n, vis[10], v[10];
set<int> ans[10];

bool judge(int x, int y) {
	memset(vis, 0, sizeof(vis));
	int num = x * y;
	while (x) {
		vis[x % 10]++;
		x /= 10;
	}
	while (y) {
		vis[y % 10]++;
		y /= 10;
	}
	while (num) {
		vis[num % 10]--;
		num /= 10;
	}
	for (int i = 0; i < 10; i++)
		if (vis[i]) return false;
	return true;
}

void solve() {
	if (!v[n]) { 
	for (int i = ten[n / 2 - 1]; i < ten[n / 2]; i++)
		for (int j = i; j < ten[n / 2]; j++) {
			if (i % 2 && j % 2) continue;
			if (!(i % 10) && !(j % 10)) continue;
			if (judge(i, j))
				ans[n].insert(i * j);
		}
	}
	v[n] = 1;
	for (set<int>::iterator it = ans[n].begin(); it != ans[n].end(); it++)
		printf("%d\n", *it);
	printf("\n");
}

int main() {
	while (~scanf("%d", &n)) {
		solve();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值