您的位置:首页 > 其它

HDU 1795 The least one【二分】

2015-08-02 10:11 501 查看

The least one

Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 535 Accepted Submission(s): 204



[align=left]Problem Description[/align]
In the RPG game “go back ice age”(I decide to develop the game after my undergraduate education), all heros have their own respected value, and the skill of killing monsters is defined as the following
rule: one hero can kill the monstrers whose respected values are smaller then himself and the two respected values has none common factor but 1, so the skill is the same as the number of the monsters he can kill. Now each kind of value of the monsters come.
And your hero have to kill at least M ones. To minimize the damage of the battle, you should dispatch a hero with minimal respected value. Which hero will you dispatch ? There are Q battles, in each battle, for i from 1 to Q, and your hero should kill Mi ones
at least. You have all kind of heros with different respected values, and the values(heros’ and monsters’) are positive.

[align=left]Input[/align]
The first line has one integer Q, then Q lines follow. In the Q lines there is an integer Mi, 0<Q<=1000000, 0<Mi<=10000.

[align=left]Output[/align]
For each case, there are Q results, in each result, you should output the value of the hero you will dispatch to complete the task.

[align=left]Sample Input[/align]

2
3
7


[align=left]Sample Output[/align]

5
11


[align=left]Author[/align]
wangye

[align=left]Source[/align]
2008
“Insigma International Cup” Zhejiang Collegiate Programming Contest - Warm Up(4)

题意:

有一个游戏,游戏中的英雄能够将比他能量少的怪兽杀掉并且要求这个怪兽的能量与英雄的能量之间没有公因数,而且一个英雄至少可以杀掉输入的怪兽的能量值的个数的怪

兽,也就是能将小于等于输入怪兽能量值小的怪兽全杀掉,又因为要求要求这个怪兽的能量与英雄的能量之间没有公因数,所以要求英雄的能量值必须是素数,并且比怪兽的能量值

要大!注:怪兽的能量值可以不是素数!

思路:

这道题比较难读懂题,我弄懂题意就花了一晚上的时间。但是理解了之后,就比较好做题了;其实这道题抽象出来的数学模型,就是让输入一个数,让求比这个数大的一个素数(这个素数是比那个数大的素数中的最小值),这个就比较简单了,我们可以用比较笨的方法,就是在大于输入的值中从小到大找素数,如果找到就输出并跳出循环;我们也可以用打表和遍历的方法做;我们还可以用二分法做;这三种方法都可以!

方法一:

代码:

/*
时间:3000MS
Time Limit Exceeded
修改后时间变成 : 2745MS
通过!!!!
*/
#include <stdio.h>
#include <math.h>
int a[10100];
int main()
{
int n,m,i,j,k;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
for(i=m+1;i<10100;i++)
{
for(j=2;j<=(int)sqrt(i*1.0);j++)//原来是 for(j=2;j<i;j++)
{
if(i%j==0)
break;
}
if(j>(int)sqrt(i*1.0))//原来是:if(j>=i)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}


方法二比较简单就不写了!

方法三:

代码:

#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

int a[10100],k;

void sushu()
{
k=0;
for(int i=2;i<10100;i++)
{
int w=0;
for(int j=2;j<=(int)sqrt(i*1.0);j++)
{
if(i%j==0)
w=1;
}
if(w==0)
a[k++]=i;
}
}

int main()
{
int n,m,i,j;
sushu();
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
j=upper_bound(a,a+k,m)-a;
printf("%d\n",a[j]);
}
return 0;
}


刚学二分,将寻找的函数自己动手写了一下,体会了一下二分的过程,具体代码如下:

#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

int a[10100],b[10100],k;

void sushu()
{
k=0;
for(int i=2;i<10100;i++)
{
int w=0;
for(int j=2;j<=(int)sqrt(i*1.0);j++)
{
if(i%j==0)
w=1;
}
if(w==0)
a[k++]=i;
}
}

int main()
{
int n,m,i,j;
sushu();
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
int left=0,right=k-1,mid;//这一部分完全可以用函数j=upper_bound(a,a+k,m)-a;a[j]来代替!
while(left<=right)
{
mid=(left+right)/2;
if(a[mid]<=m)	left=mid+1;
else	right=mid-1;
}
printf("%d\n",a[left]);//这里面,如果用a[ringt]会是等于那个值,如果是a[left]则会取到大于那个值得最小值!
}
}


还有一个代码是打表(主要是这种打表方法比较快)加遍历,这个方法最快,所以也要掌握,代码如下:

/*
打表的方法!!!!!!!!!
用时:780MS
*/
#include <stdio.h>
int a[10100];
int main()
{
int i,j,k,n,m,t;
a[1]=1;
for(i=2;i<10100/i;i++)
for(j=2;j<10100/i;j++)
{
if(a[i]==0)
{
a[i*j]=1;
}
}
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
for(i=m+1,t=0;i<10100;i++)
{
if(a[i]==0)
{
break;
}
}
printf("%d\n",i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: