Codeforces 665D. Simple Subset
2016-04-23 18:14
246 查看
[align=center]time limit per test[/align]
[align=center]1 second[/align]
[align=center]memory limit per test[/align]
[align=center]256 megabytes[/align]
[align=center]input[/align]
[align=center]standard input[/align]
[align=center]output[/align]
[align=center]standard output[/align]
A tuple of positive integers {x1, x2, ..., xk}
is called simple if for all pairs of positive integers (i, j) (1 ≤ i < j ≤ k),
xi + xj is a prime.
You are given an array a with
n positive integers a1, a2, ..., an
(not necessary distinct). You want to find a simple subset of the array
a with the maximum size.
A prime number (or a prime) is a natural number greater than
1 that has no positive divisors other than 1 and itself.
Let's define a subset of the array a as a tuple that can be obtained from
a by removing some (possibly all) elements of it.
n (1 ≤ n ≤ 1000) — the number of integers in the array
a.
The second line contains n integers
ai (1 ≤ ai ≤ 106)
— the elements of the array a.
m — the maximum possible size of simple subset of
a.
On the second line print m integers
bl — the elements of the simple subset of the array
a with the maximum size.
If there is more than one solution you can print any of them. You can print the elements of the subset in any order.
Output
Input
Output
Input
Output
Input
Output
[align=left]
[/align]
这道题其实脑补数学规律挺简单的,但之后的判定挺麻烦的。复习了素数筛法和二分。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,a[1005],ct,pri[200002],mn[2000002],zz,ji,ou;
void init()
{
scanf("%d",&n);
int i;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) ct++;
else if(a[i]%2==1) ji++;
else ou++;
}
}
void prime()
{
int i,j;
for(i=2;i<=2000000;i++){
if(!mn[i]) {pri[++zz]=i; mn[i]=i;}
for(j=1;j<=zz,pri[j]*i<=2000000;j++){
mn[pri[j]*i]=pri[j];
if(i%pri[j]==0) break;
}
}
}
bool check(int x)
{
int l=1,r=zz,mid;
while(l<r){
mid=(l+r)>>1;
if(pri[mid]<x) l=mid+1;
else r=mid;
}
if(pri[r]==x) return true;
return false;
}
void judge1()
{
int i,j;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if((a[i]+a[j])%2==0) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge2()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("2\n%d %d\n",a[i],1); return ;
}
}
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if(a[i]==1||a[j]==1||((a[i]+a[j])%2==0)) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge3()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("%d\n",ct+1);
for(j=1;j<=ct;j++) printf("1 ");
printf("%d\n",a[i]); return ;
}
}
printf("%d\n",ct); for(j=1;j<=ct;j++) printf("1 ");
}
void work()
{
if(ct==0){
if(ji==0||ou==0) printf("1\n%d",a[1]);
else judge1();
}
else if(ct==1){
if(ou==0) printf("1\n1");
else judge2();
}
else{
if(ou==0){
printf("%d\n",ct);
for(int i=1;i<ct;i++) printf("1 "); puts("1");
return ;
}
else judge3();
}
}
int main()
{
init(); prime(); work();
return 0;
}
[align=center]1 second[/align]
[align=center]memory limit per test[/align]
[align=center]256 megabytes[/align]
[align=center]input[/align]
[align=center]standard input[/align]
[align=center]output[/align]
[align=center]standard output[/align]
A tuple of positive integers {x1, x2, ..., xk}
is called simple if for all pairs of positive integers (i, j) (1 ≤ i < j ≤ k),
xi + xj is a prime.
You are given an array a with
n positive integers a1, a2, ..., an
(not necessary distinct). You want to find a simple subset of the array
a with the maximum size.
A prime number (or a prime) is a natural number greater than
1 that has no positive divisors other than 1 and itself.
Let's define a subset of the array a as a tuple that can be obtained from
a by removing some (possibly all) elements of it.
Input
The first line contains integern (1 ≤ n ≤ 1000) — the number of integers in the array
a.
The second line contains n integers
ai (1 ≤ ai ≤ 106)
— the elements of the array a.
Output
On the first line print integerm — the maximum possible size of simple subset of
a.
On the second line print m integers
bl — the elements of the simple subset of the array
a with the maximum size.
If there is more than one solution you can print any of them. You can print the elements of the subset in any order.
Examples
Input2 2 3
Output
2 3 2
Input
2 2 2
Output
1 2
Input
3 2 1 1
Output
3 1 1 2
Input
2 83 14
Output
2 14 83
[align=left]
[/align]
题解
It has been a long day from my last blog. 人生莫名其妙地改变了轨迹……总之又开始做一些题了。今后的文章大多都并不是为了提供题解而写,而是为了提醒自己一些写法、算法、数据结构之类的,可能经过数次修改,并不漂亮而且可能有并不恰当的地方。这道题其实脑补数学规律挺简单的,但之后的判定挺麻烦的。复习了素数筛法和二分。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,a[1005],ct,pri[200002],mn[2000002],zz,ji,ou;
void init()
{
scanf("%d",&n);
int i;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) ct++;
else if(a[i]%2==1) ji++;
else ou++;
}
}
void prime()
{
int i,j;
for(i=2;i<=2000000;i++){
if(!mn[i]) {pri[++zz]=i; mn[i]=i;}
for(j=1;j<=zz,pri[j]*i<=2000000;j++){
mn[pri[j]*i]=pri[j];
if(i%pri[j]==0) break;
}
}
}
bool check(int x)
{
int l=1,r=zz,mid;
while(l<r){
mid=(l+r)>>1;
if(pri[mid]<x) l=mid+1;
else r=mid;
}
if(pri[r]==x) return true;
return false;
}
void judge1()
{
int i,j;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if((a[i]+a[j])%2==0) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge2()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("2\n%d %d\n",a[i],1); return ;
}
}
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if(a[i]==1||a[j]==1||((a[i]+a[j])%2==0)) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge3()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("%d\n",ct+1);
for(j=1;j<=ct;j++) printf("1 ");
printf("%d\n",a[i]); return ;
}
}
printf("%d\n",ct); for(j=1;j<=ct;j++) printf("1 ");
}
void work()
{
if(ct==0){
if(ji==0||ou==0) printf("1\n%d",a[1]);
else judge1();
}
else if(ct==1){
if(ou==0) printf("1\n1");
else judge2();
}
else{
if(ou==0){
printf("%d\n",ct);
for(int i=1;i<ct;i++) printf("1 "); puts("1");
return ;
}
else judge3();
}
}
int main()
{
init(); prime(); work();
return 0;
}
相关文章推荐
- 快速排序里的学问:从猜数字开始
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- Search Insert Position,Search for a Range,Pow(x, n),Sqrt(x)
- Find Minimum in Rotated Sorted Array II
- [LeetCode] Sqrt(x)
- [LeetCode] Pow(x, n)
- [LeetCode] Search Insert Position
- [LeetCode] Search for a Range
- [LeetCode] Search in Rotated Sorted Array
- PAT 1057 Stack (30)
- int sqrt(int x)
- Pow(x, n)
- Find Minimum in Rotated Sorted Array
- Divide Two Integers
- 信息竞赛学习笔记:POJ3579中位数(二分)
- acm解题报告 HDU 2141 Can you find it?
- acm解题报告 HDU 2199 Can you solve this equation?
- acm解题报告 HDU 2899 Strange fuction
- acm解题报告 HDU 1969 Pie
- acm解题报告 HDU 1061 Rightmost Digit