SGU 159.Self-Replicating Numbers

时间限制:0.5s

空间限制:6M

题意:

        在b(2<b<36)进制中,找到所有长度为n(0<n<2000)的自守数k,满足k^2%b^n=k,字典序输出。

        如 十进制中     9376^2 = 87909376   后面4位数都是9376.

 

 

 

 

 


Solution:

               可以发现长度为n的满足要求的数中,其后n-1位也是自守数。

               这样的数是很稀疏的,可以直接从n=1的情况开始搜索。当找到长度为n的数时记录,排序输出即可。

 

 

code

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int b, n;
struct node {
	int s[2009];
	bool operator < (const node &A) const {
		for (int i = n; i > 0; i--) {
			if (A.s[i] > s[i]) return 1;
			if (A.s[i] < s[i]) return 0;
		}
	}
} a;
vector<node> ans;
void Find (int d, int k) {
	if (k == n + 1) {
		if (a.s[n] != 0||n==1) ans.push_back (a);
		return ;
	}
	for (int i = 0; i < b; i++) {
		int tem = d + (i * a.s[1] << 1);
		for (int i = 2; i < k; i++)
			tem += a.s[i] * a.s[k - i + 1];
		if ( tem % b == i) {
			a.s[k] = i;
			Find (tem / b, k + 1);
		}
	}
}
int main() {
	cin >> b >> n;
	for (int i = 0; i < b; i++) {
		if (i * i % b == i) {
			a.s[1] = i;
			Find (i * i / b, 2);
		}
	}
	sort (ans.begin(), ans.end() );
	cout << (int) ans.size() << endl;
	for (int i = 0; i < (int) ans.size(); i++) {
		for (int j = n; j > 0; j--)
			if (ans[i].s[j] <= 9)
				putchar (char ('0' + ans[i].s[j]) );
			else        putchar ('A' + ans[i].s[j] - 10);
		cout << endl;
	}
	return 0;
}

 

  

 

posted @ 2014-08-11 14:40  keambar  阅读(270)  评论(0编辑  收藏  举报