暴力枚举--回文质数(luoguP1217 [USACO1.5] )

目录:

        【题目描述】

        【AC代码】

        【回文数和质数】

        【作者思路】

        【一些闲话】

【题目描述】

因为 151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151 是回文质数。

写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)[a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。

第一行输入两个正整数 a 和 b。

输出一个回文质数的列表,一行一个。

输入:5 500

输出:

5

7

11

101

131

151

181

191

313

353

373

383

【AC代码】

#include <bits/stdc++.h>
using namespace std;
bool check(int x)//判断该回文数是否为质数
{
	for(int i=2;i<=sqrt(x);i++)
	{
		if(x%i==0)
		{
			return false;
		}
	}
	return true;
}
int main()
{
	int a,b;
	cin>>a>>b;
	int d1,d2,d3,d4,d5,d6,d7;
	int palindrome;
	if(a<=10)//产生从0到10的回文数,此时回文数是一位
	{
		for(int i=2;i<=10;i++)
		{
			if(i>b)//如果目前产生的回文数大于b,程序结束
			{
				return 0;
			}
			if(check(i)&&i>=a)//判断当前回文数是否为质数,并是否满足>=a
			{
				cout<<i<<endl;//如果满足条件输出并换行
			}
		}
	}
	if(a<=100)//产生从11到100的回文数,此时回文数是两位
	{
		for(int i=11;i<=100;)//原理同上
		{
			if(i>b)
			{
				return 0;
			}
			if(check(i)&&i>=a)
			{
				cout<<i<<endl;
			}
			i+=11;//在11到100中,只有11的倍数才是回文数,例如22,33
		}
	}
	if(a<=999)产生从101到999的回文数,此时回文数是三位
	{
		for(d1=1;d1<=9;d1+=2)//只有奇数才可能是素数,d1作为个位数字必须是奇数,所以+2
	{
		for(d2=0;d2<=9;d2++)//d2没有奇数要求,所以+1
		{
			palindrome=100*d1+10*d2+d1;//产生三位回文数的模板
			if(palindrome>b)
			{
				return 0;
			}
			if(check(palindrome)&&palindrome>=a)
			{
				cout<<palindrome<<endl;
			}
		}
	}
	}
	
	if(a<=9999)//此时输出的回文数是四位
	{
		for(d1=1;d1<=9;d1+=2)
	{
		for(d2=0;d2<=9;d2++)
		{
			palindrome=1000*d1+100*d2+d2*10+d1;//产生四位回文数的模板
			if(palindrome>b)
			{
				return 0;
			}
			if(check(palindrome)&&palindrome>=a)
			{
				cout<<palindrome<<endl;
			}
		}
	}
	}
	if(a<99999)
	{
		for (d1 = 1; d1 <= 9; d1+=2) //5
	{    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) 
	 {
         for (d3 = 0; d3 <= 9; d3++) 
		 {
           palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;
           if(palindrome>b)
			{
				return 0;
			}
		   if(check(palindrome)&&palindrome>=a)
			{
				cout<<palindrome<<endl;
			}
     	}
     }
 	}
	}
	if(a<999999)//6
	{
		for (d1 = 1; d1 <= 9; d1+=2) //5
	{    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) 
	 {
         for (d3 = 0; d3 <= 9; d3++) 
		 {
           palindrome = 100000*d1 + 10000*d2 +1000*d3 +100*d3+ 10*d2 + d1;
           if(palindrome>b)
			{
				return 0;
			}
		   if(check(palindrome)&&palindrome>=a)
			{
				cout<<palindrome<<endl;
			}
     	}
     }
 	}
	}
	if(a<9999999)//7
	{
		for (d1 = 1; d1 <= 9; d1+=2) //5
	{    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) 
	 {
         for (d3 = 0; d3 <= 9; d3++) 
		 {
		 	for(d4=0;d4<=9;d4++)
		 	{
		 		palindrome = 1000000*d1 + 100000*d2 +10000*d3 +1000*d4+100*d3+ 10*d2 + d1;
	           if(palindrome>b)
				{
					return 0;
				}
			   if(check(palindrome)&&palindrome>=a)
				{
					cout<<palindrome<<endl;
				}
			 }
           
     	}
 	}
	}
	}
	if(a<99999999)//测试案例数据范围5~1e8,所以到此产生回文数完全够用
	{
		for (d1 = 1; d1 <= 9; d1+=2) //d1作为头和尾部数字出现
	{    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) 
	 {
         for (d3 = 0; d3 <= 9; d3++) 
		 {
		 	for(d4=0;d4<=9;d4++)
		 	{
		 	palindrome=10000000*d1+1000000*d2+100000*d3+10000*d4+1000*d4+100*d3+10*d2 +
d1;
	           if(palindrome>b)
				{
					return 0;
				}
			   if(check(palindrome)&&palindrome>=a)
				{
					cout<<palindrome<<endl;
				}
			 }
           
     	}
 	}
	}
	}
	return 0;
}

【回文数与质数】

回文数产生模板:

for (d1 = 1; d1 <= 9; d1+=2) {    // 只有奇数才会是素数
     for (d2 = 0; d2 <= 9; d2++) {
         for (d3 = 0; d3 <= 9; d3++) {
           palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
         }
     }

 质数判断模板:

bool check(int x)//判断该回文数是否为质数,1不是质数
{
    for(int i=2;i<=sqrt(x);i++)//
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

【作者思路】

作者首先想到的就是不停循环a~b并判断是否为回文数或质数,后来根据题目提示又想到可以产生回文数,并判断该数是否为质数。相比于直接循环判断该方法时间复杂度更小,AC只用53ms,而用循环判断AC需要183ms,当然二者本质还是暴力枚举

【一些闲话】

欢迎各位dalao指出错误,提问,博主(bme专业)一定尽力解答

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值