问题 A: 小刷上学记
时间限制: 1 Sec 内存限制: 128 MB
提交: 186 解决: 33
[提交][状态][讨论版]
题目描述
有n个小朋友一起结伴同行去上学,每个小朋友的口袋里都有一些糖果,孩子的世界总是单纯而又可爱,现在其中的小刷提出了一个问题,如果把某些人(大于等于1个人)的糖果组合起来,能否组合出素数个糖果呢?如果能够组合出素数个糖果,能组成的最大的素数又是多少呢?如果不能,又最接近于哪个素数呢?如果一样接近,最大的又是哪个素数呢?
看,小刷的世界就是这么单洁而又可爱!
输入
第一行输入一个n,紧接着下一行输入n个整数ai表示n个小朋友口袋里的糖果。
(n <= 100 ai <= 10000,ai之和<=10000)
输出
对于每组数据,输出一个数answer,表示能组合出来的最大的素数,如果不能组合出素数, 输出能组合出来的最接近的素数,如果有多个,输出最大的那个。即满足abs(answer - i)是最小的,且answer最大。( i是能通过若干个小朋友组合出来的糖果数量)输出的素数小于10000
样例输入
1
3
1
10
样例输出
3
11
#include <bits/stdc++.h>
using namespace std;
int m[100000];
const int maxx=10100;
int a[maxx];
int dp[maxx];
int sum,f;
void pd(int n) //得到小于10000的素数
{
m[2]=1;
for(int i=3; i<=10000; i++)
{
int p=0;
for(int j=2; j<=sqrt(i); j++)
{
if(i%j==0)
{
p=1;
break;
}
}
if(p==0)
{
m[i]=1;
}
}
}
void print(int n)
{
for(int i=1; i<=sum; i++)
cout<<dp[i]<<" ";
cout<<endl;
}
void finding(int n)
{
int p1,p2,ans;
for(int i=sum;;i--)
{
if(m[i]==1) {p1=i;break;}
}
for(int i=sum+1;;i++)
{
if(m[i]==1) {p2=i;break;}
}
if(abs(p1-sum)>abs(p2-sum))
printf("%d\n",p2);
else if(abs(p1-sum)<abs(p2-sum))
printf("%d\n",p1);
else
printf("%d\n",p2);
}
int main()
{
int n;
pd(1);
while(~scanf("%d",&n))
{
sum=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
sum=sum+a[i];
}
//cout<<sum<<endl;
dp[0]=1;
for(int i=1; i<=n; i++)
{
for(int j=sum; j>=a[i]; j--)
{
if(dp[j-a[i]]==1)
dp[j]=1;
}
}
//print(n);
int p=0;
for(int i=1; i<=sum; i++)
{
if(dp[i]==1&&m[i]==1) {p=1;f=i;}
}
if(p==1) printf("%d\n",f);
else
finding(f);
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
}
return 0;
}