1425:质数和

该程序使用埃拉托斯特尼筛法找到一定范围内的质数,并计算特定位数质数之和。对于给定的a和b,分别计算前a位和后b位质数的组合,并求和。样例中,对于a=12和b=55,输出所有符合条件的质数和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1425:质数和

描述
有一个a+b位的正整数,前a位是质数,后b位也是质数,求所有符合条件的数字和。
注意:前a位的质数不可以0开头,否则拼出的数字不是a+b位。后b位的质数可以是0开头。例如当a=1,b=2时,207是一个符合条件的数字。

输入
多组案例。一个正整数n,表示案例的数量。(n<=40)
每组案例由两个正整数a和b组成(1<=a<=7,1<=b<=7,且保证a+b<=10)

输出
针对每组案例,输出一个长整数,表示所有符合条件的数字和。
每组案例输出完都要换行。

样例输入
2
1 2
5 5

样例输出
46740
430358607365438931

#include<iostream>
#include<cmath>
#include<memory>
using namespace std;
typedef unsigned char BYTE;//无符号单字节的东西
bool getValue(BYTE* s, int number)
{
	return s[number / 8] & (1 << (number % 8));
	//当number=2时,return s[0]&(1<<2) 
	//11111100 & 00000100 = 00000100 -> true
	//11111000 & 00000100 = 00000000 -> false
	//true->number 是质数 false->number 不是质数
}
void setValue(BYTE* s, int number)
{
	BYTE t = ~(1 << (number % 8));
	s[number / 8] &= t;
	//当number=4时,s[0]=11111100,1 << 4 = 00010000
	//t = 11101111
	//s[0] = s[0]&t
	//11111100&11101111=11101100
}
int power(int a, int b)
{
	int mul = 1;
	for (int i = 0; i < b; i++)
	{
		mul *= a;
	}
	return mul;
}
int main()
{
	//用埃拉托斯特尼筛法检测质数。用一个位记录某个数字是不是质数,数字x在s[x/8]的第x%8个位上(最低位为第0位)
	const int MAX = 10000000;
	BYTE* s = new BYTE[MAX / 8];
	for (int i = 0; i < MAX / 8; i++)//假设都是质数
	{
		s[i] = 255;//二进制11111111
	}
	s[0] = s[0] ^ 3;
	//0和1不是质数(00000000~11111111=11111100)
	for (int i = 2; i <= sqrt(MAX); i++)
	{
		if (getValue(s, i))
		{
			for (int j = i * i; j < MAX; j += i)
			{
				setValue(s, j);
			}
		}
	}
	unsigned long long int t[8] = { 0 };
	//t[i]表示i位数中质数的和
	unsigned long long int t2[8] = { 0 };
	//t的累加,t2[3]表示3位数+2位数+1位数的和
	unsigned int u[8] = { 0 };
	//u[i]表示i位数中质数的个数
	unsigned int u2[8] = { 0 };
	//u的累加
	int v = 1;
	for (int i = 1; i <= 7; i++)
	{
		for (int j = v; j < v * 10; j++)
		{
			if (getValue(s, j))
			{
				t[i] += j;
				u[i]++;
			}
		}
		v *= 10;
	}
	for (int i =1;i<=7;i++)
	{
		t2[i] = t2[i - 1] + t[i];
		//t2[2]=t2[1]+t[2]=t[1]+t[2]
		u2[i] = u2[i - 1] + u[i];
	}
	delete[]s;
	int n;
	cin >> n;
	while (n--)
	{
		int a, b;
		cin >> a >> b;
		unsigned int c = power(10, b);
		unsigned long long int result = t[a] * u2[b] * c + t2[b] * u[a];
		cout << result << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值