HDU-1431(素數迴文)(思維)(dfs+素數判定)

HDU-1431(素數迴文)

素數迴文

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 16595    Accepted Submission(s): 3702


Problem Description
xiaoou33對既是素數又是迴文的數特別感興趣。比如說151既是素數又是個迴文。現在xiaoou333想要你幫助他找出某個範圍內的素數迴文數,請你寫個程序找出 a 跟b 之間滿足條件的數。(5 <= a < b <= 100,000,000);
 

Input
這裏有許多組數據,每組包括兩組數據a跟b。
 

Output
對每一組數據,按從小到大輸出a,b之間所有滿足條件的素數迴文數(包括a跟b)每組數據之後空一行。
 

Sample Input
5 500
 

Sample Output
5 7 11 101 131 151 181 191 313 353 373 383

剛開始就感覺這道題有點麻煩。起初的思路是先打素數表,再從素數中查找符合條件的迴文數。感覺會超時,5 <= a < b <= 100,000,000,由於範圍比較大,於是就單單測試了一下打表,結果在編譯器上就運行了2~3秒,按照這樣的思路寫最終肯定會超時。於是想了很久發現可以利用迴文數的對稱性爲切入點,可能還有解決的希望。

(先找出迴文數,再判斷是不是素數)

例:樣例:5   500

首先 ;

一位數字:   2、3、5、7

       兩位:  11  

      三位:   101   131    151

  如果是奇數位:通性:  ........x y z x y......(對稱)

以:x y z x y爲例,只需變化3個就可以了,x、y、z分別取值0~9(dfs)就可以打印出5位數的全部迴文數,然後再對迴文數判斷是不是素數

如果是偶數位:通性:  .......x y z z y x......(對稱)

以:x y z z x y爲例,只需變化3個就可以了,x、y、z分別取值0~9(dfs)就可以打印出6位數的全部迴文數,然後再對迴文數判斷是不是素數

就樣例而言:

先打印  1 位的迴文數,再打印 2 位的迴文數,再打印 3 位 的迴文數。。。。。。。。

該題思路:( for循環 + ( dfs + 素數判斷 ) ),(for循環控制位數,dfs控制打印迴文數,prim進行素數判斷)

My  solution:

/*2016.3.31*/

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
int map[100000030],cnt1,cnt2,a1[20],k1,k2,vis;
int prim(int t)//判斷素數 
{
	int i,j,k;
	for(i=2;i*i<=t;i++)
	{
		if(t%i==0)
		return 0;
	}
	if(t==1)//1不是素數,這點容易遺忘 
	return 0;
	return 1;
}
void dfs(int t1,int t2)
{
	int i,j,k,sum;
	if(t2<t1)//此次查詢完成 
	{
		if(a1[vis]%2)//優化,最後一位數字如果是偶數的話,這個數肯定是偶數,不是素數 (同時巧妙化解了首位數字不能爲0的情況)
		{
			sum=0;
			for(i=1;i<=vis;i++)//把這個數在數組中的數值位轉換爲整數sum 
			{
				sum=a1[i]+sum*10;
			}
			if(prim(sum)&&(sum>=k1&&sum<=k2))//sum不僅要是素數,而且還得大於等於a小於等於b 
			printf("%d\n",sum);
			return ;
		}
		return ;
	}
	for(i=0;i<=9;i++)//控制每個數值位上的數字 
	{
		a1[t1]=a1[t2]=i;//由於對稱,所以相等 
		dfs(t1+1,t2-1);//左右各往裏縮進一位 ,這一步特別重要 
	}
}
int main()
{
	int i,j,k,n,m,a,b;
	while(scanf("%d%d",&k1,&k2)==2)
	{
		a=k1;b=k2;
		cnt1=cnt2=0;
		while(b)
		{
			b=b/10;
			cnt2++;//cnt2記錄b的位數 
		}
		while(a)
		{
			a=a/10;
			cnt1++;//cnt1記錄a的位數 
		}
		for(i=cnt1;i<=cnt2;i++)//控制位數 
		{
			vis=i;//vis記錄當前查詢的最大位數 
			dfs(1,i);//在當前位數中,查找滿足題目要求的迴文素數 
		}
		printf("\n");	
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章