烈焰风暴
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
烈焰风暴是游戏「魔兽争霸Ⅲ」中的一项技能,血魔法师召唤出一道灼热的火墙,给一定范围内的 6 个单位造成伤害,并在一定时间内对这些单位造成持续伤害 (快捷键 "F"),如图所示:
这里只是给大家科普一下,与本题的设定不同。
现在,一些小兵排列整齐以一条线的方式,通过传送门进攻你的大本营。
为了简化问题,我们假设烈焰风暴的作用范围是一个半径为 R 的圆(包括圆上的点),可以秒杀作用范围内的数量不限的小兵。所有小兵都在一条直线上,其位置以坐标的形式给出,并且给出烈焰风暴的作用半径以及释放一次技能所需要的魔法值 m,请你求出至少需要多少魔法才能杀死所有小兵。
Input
输入数据有多组(数据组数不超过 200),到 EOF 结束。
对于每组数据:
- 第 1 行先给出小兵数量 n (1 <= n <= 1000),半径 R (1 <= R <= 20) 和魔法值 m (1 <= m <= 100)。
- 第 2 行输入 n 个小兵的坐标 x (0 <= x <= 10000)。
输入数据均为整数,一行内的整数两两之间用空格隔开。
Output
在输出的最开始一行先输出 ”Good Luck” (无论几组数据它只在开头输出一次)。
对于每组数据,先输出 ”Case #i: ” (i 从 1 开始计数),表示当前是第几组数据,之后输出至少需要的魔法。
在所有数据都处理完后,输出一行 ”QAQ”。
上述输出均不包含引号。
Example Input
5 2 4 1 2 3 4 5 5 2 4 1 2 4 6 5
Example Output
Good Luck Case #1: 4 Case #2: 8 QAQ
Hint
Author
MLE_kenan
一开始想用固定的几个位置来放大招无奈不对,。。。。
之后看的别人的代码才知道原来不过是迭代法,加上从第一个开始出现的小兵开始放技能,而不是五个五个的放。
答案一:快排实现版
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string.h>
#include<math.h>
/*#include<algorithm>
#include<iostream>
using namespace std;*/
void f(int a[],int l,int r)
{
int i = l, j = r, t = a[l];
if(l>=r) return ;
while(i<j)
{
while(a[j]>=t&&i<j) j--;
a[i] = a[j];
while(a[i]<=t&&i<j) i++;
a[j] = a[i];
}
a[i] = t;
f(a,l,i-1);
f(a,i+1,r);
#include<iostream>
using namespace std;*/
void f(int a[],int l,int r)
{
int i = l, j = r, t = a[l];
if(l>=r) return ;
while(i<j)
{
while(a[j]>=t&&i<j) j--;
a[i] = a[j];
while(a[i]<=t&&i<j) i++;
a[j] = a[i];
}
a[i] = t;
f(a,l,i-1);
f(a,i+1,r);
}
int main()
{
{
printf("Good Luck\n");
int n,r,m,k = 1,a[1010];
while(~scanf("%d%d%d",&n,&r,&m))
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
f(a,0,n-1);
r = 2*r;
int sum = m;
for(int i=0;i<n;i++)
{
if(a[i]-a[0]>r)
{
sum += m;
a[0]=a[i];
}
}
printf("Case #%d: %d\n",k,sum);
k++;
}
int n,r,m,k = 1,a[1010];
while(~scanf("%d%d%d",&n,&r,&m))
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
f(a,0,n-1);
r = 2*r;
int sum = m;
for(int i=0;i<n;i++)
{
if(a[i]-a[0]>r)
{
sum += m;
a[0]=a[i];
}
}
printf("Case #%d: %d\n",k,sum);
k++;
}
printf("QAQ\n");
return 0;
}
答案2:
桶排序实现版
关键代码
scanf("%d",&n);
while(n--)
{
scanf("%d",&k);
a[k]++;
}
sum = 0;
for(int i=0;i<=10000;i++)
{
if(a[i]!=0)
{
sum+=m;
for(j=i;j<=i+2 *r&&j<=10000;j++)
{
a[j] = 0;
}
}
}
printf("%d",sum);
3:自己的错误代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
/*#include<algorithm>
#include<iostream>
using namespace std;*/
int main()
{
printf("Good Luck\n");
int n,r,m,l=0;
while(~scanf("%d%d%d",&n,&r,&m))
{
int i,k,a[10001]={0},f = 0,sum=0;
for(i=1;i<=n;i++)
{
int y;
scanf("%d",&y);
a[y] ++;
}
int h = 2*r+1;
for(k = r+1;k<=10000;k=k+h)
{
int u = 0;
for(i=k-2;i<=k+2;i++)
{
if(a[i]==1)
{
u++;
a[i] = 0;
f++;
if(f==n)
{
break;
}
}
}
if(u)
{
sum += m;
}
if(f==n)
{
break;
}
}
l++;
printf("Case #%d: %d\n",l,sum);
}
printf("QAQ\n");
return 0;
}
#include<string.h>
#include<math.h>
/*#include<algorithm>
#include<iostream>
using namespace std;*/
int main()
{
printf("Good Luck\n");
int n,r,m,l=0;
while(~scanf("%d%d%d",&n,&r,&m))
{
int i,k,a[10001]={0},f = 0,sum=0;
for(i=1;i<=n;i++)
{
int y;
scanf("%d",&y);
a[y] ++;
}
int h = 2*r+1;
for(k = r+1;k<=10000;k=k+h)
{
int u = 0;
for(i=k-2;i<=k+2;i++)
{
if(a[i]==1)
{
u++;
a[i] = 0;
f++;
if(f==n)
{
break;
}
}
}
if(u)
{
sum += m;
}
if(f==n)
{
break;
}
}
l++;
printf("Case #%d: %d\n",l,sum);
}
printf("QAQ\n");
return 0;
}
虽然只是找开头的时候错了,然而却始终不对。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。