pku 1319Prime Cuts

来源:互联网 发布:wpf软件 编辑:程序博客网 时间:2024/05/16 09:33



Prime Cuts

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1786    Accepted Submission(s): 755


Problem Description
A prime number is a counting number (1, 2, 3, ...) that is evenly divisible only by 1 and itself. In this problem you are to write a program that will cut some number of prime numbers from the list of prime numbers between (and including) 1 and N. Your program will read in a number N; determine the list of prime numbers between 1 and N; and print the C*2 prime numbers from the center of the list if there are an even number of prime numbers or (C*2)-1 prime numbers from the center of the list if there are an odd number of prime numbers in the list. 
 

Input
Each input set will be on a line by itself and will consist of 2 numbers. The first number (1 <= N <= 1000) is the maximum number in the complete list of prime numbers between 1 and N. The second number (1 <= C <= N) defines the C*2 prime numbers to be printed from the center of the list if the length of the list is even; or the (C*2)-1 numbers to be printed from the center of the list if the length of the list is odd. 
 

Output
For each input set, you should print the number N beginning in column 1 followed by a space, then by the number C, then by a colon (:), and then by the center numbers from the list of prime numbers as defined above. If the size of the center list exceeds the limits of the list of prime numbers between 1 and N, the list of prime numbers between 1 and N (inclusive) should be printed. Each number from the center of the list should be preceded by exactly one blank. Each line of output should be followed by a blank line. Hence, your output should follow the exact format shown in the sample output. 
 

Sample Input
21 218 218 18100 7
 

Sample Output
21 2: 5 7 1118 2: 3 5 7 1118 18: 1 2 3 5 7 11 13 17100 7: 13 17 19 23 29 31 37 41 43 47 53 59 61 67
 

Source
South Central USA 1996


解题思路:

思路一:首先看图即知需分grid和skew两种方向考虑,然后因为skew摆放不分方向,所有又有两种,总共五种情况,grid一种,skew四种;

grid没有悬念,就是a,b取整相乘就是个数,skew要分横放和竖放,现在我们算出第一排之后每放一排高度增加  sqrt(3.0) / 2.0 的高度,模拟

就可以出结果了,这里注意无论 a 或 b 小于1都无法放第一个下去,所以自然为0,这个特殊情况需另外考虑。

思路二:我们模拟出了结果,可以发现高度满足  sqrt(3.0) / 2.0 * i + 1 <=a 或  sqrt(3.0) / 2.0 * i + 1 <=b 都可存放pipes,解释一下这个公式:

1表示第一排的pipes的高度,后面的因为是skew存放,高度为 sqrt(3.0) / 2.0 ,i 表示最多可以存放多少排 pipes ,答案就出来了。

代码:

#include<iostream>#include<stack>#include<list>#include<cmath>#include<cctype>#include<vector>#include<queue>#include<cstdio>#include<cstring>#include<string>#include<cstdlib>#include<fstream>#include<algorithm>using namespace std;const double AddH=sqrt(3.0)/2.0;const int h=1.0;int main(int argc, char *argv[]){    int p[6], i, j, k, fc, fr;    double c, r;    while( cin>>c>>r )    {        memset(p, 0, sizeof p);        fc=int(c);        fr=int(r);        if( fr<1 || fc<1 )        {            cout<<"0 grid\n";            continue;        }        p[0]=fr*fc;        p[1]=fc;        for(i=j=1;; i++)        {            if(  AddH*i+h>r ) break;            if( j==1 )            {                p[1]+=fc-1;                j=0;            }            else            {                p[1]+=fc;                j=1;            }        }        p[2]=fr;        for(i=j=1;; i++)        {            if( AddH*i+h>c ) break;            if( j==1 )            {                p[2]+=fr-1;                j=0;            }            else            {                p[2]+=fr;                j=1;            }        }        if( c-fc>=0.5 )        {            p[3]=fc;            for(i=1;; i++)            {                if(  AddH*i+h>r ) break;                p[3]+=fc;            }        }        if( r-fr>=0.5 )        {            p[4]=fr;            for(i=1;; i++)            {                if( AddH*i+h>c ) break;                p[4]+=fr;            }        }        k=p[j=0];        for(i=1; i<5; i++)        {            if( p[i]>k )            {                k=p[i];                j=i;            }        }        cout<<k<<' ';        if( j>0 ) cout<<"skew\n";        else cout<<"grid\n";    }    return 0;}

代码二:
#include<iostream>#include<stack>#include<list>#include<cmath>#include<cctype>#include<vector>#include<queue>#include<cstdio>#include<cstring>#include<string>#include<cstdlib>#include<fstream>#include<algorithm>using namespace std;const double AddH=sqrt(3.0)/2.0;const int h=1.0;int func(double n, double m){    if( n<1 ) return 0;    int a=(int)((n-1)/(sqrt(3.0)/2.0))+1;    if( m-(int)m>=0.5 )        return a*(int)m;    return a*(int)m-a/2;}int main(int argc, char *argv[]){    double n, m;    while( cin>>n>>m )    {        int grid=(int)n*(int)m;        int ans1=func(n, m);        int ans2=func(m, n);        int skew=max(ans1, ans2);        if( skew<=grid )            cout<<grid<<" grid\n";        else cout<<skew<<" skew\n";    }    return 0;}










0 0