codechef Prime Palindromes 题解

来源:互联网 发布:linux tmp目录大小 编辑:程序博客网 时间:2024/05/15 07:12

给定一个数,求一个新数要大于等于这个数,而这个新数既要是palindromes回文又要是prime素数。

题目很简单,有人都使用取巧的方法保存好结果直接查表。

或者暴力法求解。

这里不使用保存表的方法,也不要用暴力法。- 这些方法都不好。

使用的技巧有:

1 而是使用next palindrome的技巧,只需要O(n),n是数位,可以认为是常数了。

2 判断素数的方法,时间效率是O(sqrt(n)), n是数值大小,如果是重复判断很多数是否是素数是有办法优化的,但是如果是单个素数判断的话,我还想不到,也找不到优化的方法。

不过怎么都好,下面程序假设它是需要重复判断数是素数的,那么就可以保持一个数组的方法,然后只需要判断这个数是否能被这个数组中小于这个数n的sqrt(n)除尽,就可以快速判断出这个数是否是素数了。

当然本题好像直接判断是否是素数就可以了。

原题:http://www.codechef.com/problems/PRPALIN/

全部实现上面的优化,那么程序还是非常繁琐的,也是出于学习的目的吧。

#include <assert.h>#include <string>#include <stdio.h>#include <math.h>#include <iostream>using namespace std;namespace{static const int MAX_NUM = 1100;}bool allNines(string a){bool nines = true;for (int i = 0; i < (int)a.size() && nines; i++){if (a[i] != '9') nines = false;}return nines;}string nextPalindrome(string a){if (allNines(a)){a[0] = '1';for (int i = 1; i < (int)a.size(); i++){a[i] = '0';}a.push_back('1');return a;}int mid = (a.size() >> 1);int L = mid - 1, R = mid + 1;if (a.size() % 2 == 0) R--;//确定中心int i = L, j = R;//查找不同点下标for ( ; i >= 0 && j < (int)a.size() && a[i] == a[j]; i--, j++);bool leftsmall = false;if (i < 0 || a[i] <= a[j]) leftsmall = true;//i<0排除了等于的情况了for ( ; i >= 0; i--, j++){a[j] = a[i];}if (leftsmall){int carry = 1;if (a.size() % 2){a[mid]++;if (a[mid] > '9') a[mid] = '0';else carry = 0;}i = L, j = R;while (carry){a[i]++;if (a[i] > '9') a[i] = '0';else carry = 0;a[j] = a[i];i--, j++;}}return a;}bool isPalindrome(string s){bool palin = true;for (int i = 0, j = int(s.size()) - 1; i < j; i++, j--){if (s[i] != s[j]) palin = false;}return palin;}int PrimePalindromes(){bool primes[MAX_NUM+1] = {0};for (int i = 2; i <= MAX_NUM; i++){if (!primes[i]){for (int j = (i<<1); j <= MAX_NUM; j += i){primes[j] = true;}}}int primeNums[MAX_NUM] = {0};int id = 0;for (int i = 2; i <= MAX_NUM; i++){if (!primes[i]) primeNums[id++] = i;}string s;cin>>s;int sn = stoi(s);assert(1 <= sn && sn <= 1000000);if (!isPalindrome(s)) s = nextPalindrome(s);while (true){sn = stoi(s);int sq = (int)sqrt((double)sn);bool isprimeNum = true;int i = 0;for ( ; primeNums[i] <= sq && i < id; i++){if (sn % primeNums[i] == 0){isprimeNum = false;break;}}if (isprimeNum) break;s = nextPalindrome(s);}cout<<s;return 0;}




1 0
原创粉丝点击