ZOJ-3014

27 篇文章 0 订阅
26 篇文章 0 订阅

DFS加大素数判定,本题由于数的最大值要用long long存,用那个随机化判素数方法会溢出。。只能放弃,用最原始的模因子判断。。但这个算法太慢,会超时,但本题N只有2到16,可以无耻地打表。。

求表代码:

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>

using namespace std;

namespace
{
	bool used[16];
	vector<int> res;
	long long maxv;
	string str;

	bool is_prime(long long n)
	{
		if (n == 2)
			return true;
		if (n <= 1 || n % 2 == 0)
			return false;
		for (long long i = 3; i * i <= n; i += 2)
			if (n % i == 0)
				return false;
		return true;
	}

	long long to_ten_base(const vector<int> &array, int base)
	{
		long long sum = 0;
		for (size_t i = 0; i < array.size(); i++)
			sum = array[i] + sum * base;
		return sum;
	}

	string to_string(const vector<int> &array)
	{
		string s;
		for (size_t i = 0; i < array.size(); i++)
			if (array[i] < 10)
				s += ('0' + array[i]);
			else
				s += ('A' + array[i] - 10);
		return s;
	}

	void dfs(int depth, int base, int length)
	{
		if (depth == length)
		{
			long long src = to_ten_base(res, base);
			vector<int> rever = res;
			reverse(rever.begin(), rever.end());
			long long dest = to_ten_base(rever, base);
			if (is_prime(src) && is_prime(dest) && src > maxv)
			{
				str = to_string(res);
				maxv = src;
			}
			return;
		}

		for (int i = 0; i < (res.empty() ? base : res.back()); i++)
		{
			if (!used[i])
			{
				res.push_back(i);
				used[i] = true;
				dfs(depth + 1, base, length);
				used[i] = false;
				res.pop_back();
			}
		}
	}
}

int main()
{
	memset(used, 0, sizeof(used));
	int base;
	for (base = 2; base <= 16; base++)
	{
		maxv = 0;
		for (int len = 1; len <= base; len++)
			dfs(0, base, len);
		cout << (maxv ? str : "not special") << endl;
	}
	return 0;
}

打表代码:

#include<stdio.h>

int main()
{
	char *s[] = { "not special", "not special", "not special", "21", "31", "43",
			"5421", "5431", "76531", "765421", "9875321", "9876421",
			"BA98765421", "BA8765431", "DCBA9654321", "EDCBA8765432",
			"FEDCBA8765431" };
	int n;
	while (scanf("%d", &n) != EOF)
		puts(s[n]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值