USACO 1.3 Prime Cryptarithm (crypt1)

这道题目没有花费什么时间,基本上写完就 AC 了,不过在这道题目上倒是认识到一个问题。

函数 itoa, atoi 等并非标准的 C 函数库扩展,在很多网站上大量滥用这些函数,但这些函数只能用于 VC++ 等编译器。在 G++ 等编译器中是不适用的。

/*
ID: ceeji
LANG: C++
PROG: crypt1
*/
 
#include <fstream>
#include <string>
#include <stdio.h>
#include <memory.h>
 
using namespace std;
 
const char *infile = "crypt1.in";
const char *oufile = "crypt1.out";
 
bool can[10]; // define whether the number is used.
int use[5];
int l, res = 0;
 
// ** function declare **
bool check();
bool allin(char *s);
 
// change int into char* type.
#define tostr(d,to) \
{ \
	sprintf(to, "%d", d); \
}
 
inline void init() // read file.
{
	memset(can, false, sizeof(can));
	ios::sync_with_stdio(false);
	ifstream fin(infile);
	fin >> l;
	for (int i = 0, j; i < l; ++i)
	{
		fin >> j;
		can[j] = true;
	}
	fin.close();
}
 
inline void doit(int p) // dfs.
{
	if (p == 5) // has found a result of two numbers.
	{
		if (check())
			++res;
		return;
	}
	for (int i = 0; i < 10; ++i)
		if (can[i])
		{
			if ((p == 0 || p == 3) && i == 0)
				continue;
			use[p] = i;
			doit (p+1);
		}
}
 
inline bool check() // check whether it's a good result.
{
	int a = use[2] + use[1] * 10 + use[0] * 100, b = use[3] * 10 + use[4],c = a * use[4], d = a * use[3];
	if (c > 999 || d > 999 || c < 100 || d < 100)
		return false;
	char s1[10], s2[10];
	tostr(c, s1);
	tostr(d, s2);
	if ((!allin(s1)) || (!allin(s2)))
		return false;
	int e = c + d * 10;
	if (e > 9999 || e < 1000)
		return false;
	tostr(e, s1);
	if (!allin(s1))
		return false;
	return true;
}
 
inline bool allin(char *s) // is all number in the can array?
{
	for (int i = 0; i < strlen(s); ++i)
	{
		if (!can[s[i] - '0'])
		{
			return false;
		}
	}
	return true;
}
 
inline void output() // output the result.
{
	ofstream fout(oufile);
	fout << res << endl;
	fout.close();
}
 
int main(void)
{
	init();
	doit(0);
	output();
	return 0;
}

本文版权遵循 CC BY-NC-SA 4.0发布,转载需附带本文链接。

当前页阅读量为: