1. 程式人生 > >【ACM】家喻戶曉的中藥店(待更)

【ACM】家喻戶曉的中藥店(待更)

題目連結:http://acm.nuc.edu.cn/OJ/contest/show/43/1007

【問題描述】

long_xiao和const_hhh是一對恩愛的夫妻。  

他們在京城經營著一家中藥店,夫妻二人醫術精湛、古道熱腸,雖然年過花甲,身體依然硬朗。更重要的是,他們的思維仍然十分活躍,不僅瞭解大家的要求,還能給他們許多驚喜。  

除了治病救人,他們的中藥配方還有舒筋活絡,排毒養顏的功效。正因為如此,中藥店門庭若市,甚至有人不遠千里,慕名而來。  

藥店裡藥材種類繁多,組成的配方也就非常多。為了提高服務質量,店裡的夥計灰來灰去將藥材和配方進行編號,灰來灰去可以通過配方的編號快速找到所需藥材的編號。

一天,店裡的夥計灰來灰去提議可以藉此機會來向大家普及一下數學知識,夫妻二人表示贊成,決定每週一在店門口的公告欄中釋出新的知識點。  

這週一他們提供了一個簡單但是有趣的知識點:  

“素數:一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做素數“。  

到了週末,灰來灰去為了檢驗大家對知識點的掌握情況,使得今天的配方都由三種藥材組成,所需的三種藥材的編號都為素數,且加起來等於配方的編號。因為會有多種情況出現,灰來灰去使得三個素數的乘積最大。

現在,藥店會給你開出一劑配方,編號為n。如果你能把他拆成3個素數的和或者告訴灰來灰去無法拆成3個素數的和,那麼灰來灰去就可以快速找到藥材,並免費贈送你一副他們的鎮店配方。

【輸入描述】

輸入第一行包含一個正整數T,代表有T次配方的詢問。

對於每組資料,輸入包含一個正整數n(1<=n<=10000),代表配方的編號。

【輸出描述】

對於每組資料,如果n不能寫成三個素數的和,輸出-1。  
否則在一行從小到大輸出三個素數以及最大乘積。

Time Limit Exceeded 

#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

int a[10005];

void isprime()
{
	memset(a,0,sizeof(a));
	int i;
	for(i=2;i<=10000;i++)
	{
		if(i==2|| i==3)
		{
			a[i]=i;
			continue;
		}
		if(i%6!=1 && i%6!=5)
		{
			a[i]=0;
			continue;
		}
		int t=(int)sqrt(i);
		for(int j=5;j<=t;j+=6)
		{
			if(i%j==0 || i%(j+2)==0)
			{
				a[i]=0;
				break;
			}
		}
		a[i]=i;
	}
}

int main ()
{
	isprime();
	int T,n,i,j,x,y,z,zz;
	long long int Max,r;
	scanf("%d",&T);
	while(T--)
	{
		Max=-1;
		scanf("%d",&n);
		for(i=2;i<=n;i++)
		{
			for(j=2;j<=n;j++)
			{
				if(a[i] && a[j])
				{
					z=n-a[i]-a[j];
					if(z>=2 && a[z])
					{
						r=a[i]*a[j]*z;
						if(r>Max )
						{
							Max=r;
							x=min(a[i],min(a[j],z));
							zz=max(a[i],max(a[j],z));
							y=n-x-zz;
						}
					}
				}
			}
		}
		if(Max==-1)
		{
			printf("-1\n");
		}
		else
		{
			printf("%d %d %d %d\n",x,y,zz,Max);
		}
	}
	return 0;
}