A - Serval vs Monster
答案为h/a向上取整
#include
#define ll long long
using namespace std;
#define maxn 200000+66
int main()
{
int h,a;
while(cin>>h>>a)
{
cout<
B - Common Raccoon vs Monster
直接比较和与h的值即可
#include
#define ll long long
using namespace std;
#define maxn 200000+66
int main()
{
int h,a;
while(cin>>h>>a)
{
int s=0;
for(int i=1;i<=a;i++)
{
int x;
cin>>x;
s+=x;
}
if(s>=h)
{
cout<<"Yes"<
C - Fennec vs Monster
排序,然后累加前h-k项即可
#include
#define ll long long
using namespace std;
#define maxn 200000+66
int a[maxn];
bool cmp(int a,int b)
{
return a>h>>k)
{
for(int i=1;i<=h;i++)
{
cin>>a[i];
}
sort(a+1,a+h+1);
ll s=0;
for(int i=1;i<=h-k;i++)
{
s+=a[i];
}
cout<
D - Caracal vs Monster
一血量为X的怪兽,若X<=1,则被攻击后消失,否则变为两个血量为X/2向下取整的怪兽,问最小攻击多少次使得怪兽全部消灭。
一看就是有规律,利用队列打表,打表程序如下:
#include
#define ll long long
using namespace std;
#define maxn 200000+66
int a[maxn];
bool cmp(int a,int b)
{
return aq;
int main()
{
ll h,k;
for(int h=1;h<=200;h++)
{
while(q.size())q.pop();
q.push(h);
ll ans=0;
while(q.size())
{
int x=q.front();
q.pop();
ans++;
//cout<1)
{
q.push(x/2);
q.push(x/2);
}
}
cout<
发现有个规律: a[i]=2*a[i-1]+1 那么只要锁定给出的是第几项就好了。
就是让它不断/2,看能除几次。
#include
#define ll long long
using namespace std;
#define maxn 200000+66
ll a[maxn];
int main()
{
ll h,k;
a[0]=1;
for(int i=1;i<=100000;i++)
{
a[i]=2*a[i-1]+1;
}
while(cin>>h)
{
ll ans=0;
int cnt=0;
while(h>0)
{
h/=2;
cnt++;
}
cout<
E - Crested Ibis vs Monster
怪兽有H血量,你有N种技能,每种技能有A攻击力和B体力消耗,问能消灭怪兽用的最小体力消耗。
完全背包问题,dpi即为装入i攻击力的最小体力消耗,从m开始枚举装入i攻击力所得体力消耗最小值,取最小的。
#include
using namespace std;
const int maxn = 1000+20;
const int INF = 0x3f3f3f3f;
int p[maxn], v[maxn];
int dp[20000+50];
int main()
{
int n, m;
while(scanf("%d %d", &m, &n)!=EOF) {
for(int i = 1; i <= n; i++) {
scanf("%d %d", &v[i], &p[i]);
}
memset(dp, INF, sizeof(dp));
dp[0] = 0;
for(int i = 1; i <= n; i++) {
for(int j = v[i]; j <= 20000; j++) {
dp[j] = min(dp[j], dp[j-v[i]] + p[i]);
}
}
int maxx = dp[m];
for(int i=m;i<=20000;i++)
{
if(dp[i]
F - Silver Fox vs Monster
给出怪物的位置和生命力,还有伤害范围d,在i处放炸弹伤害区域为i-d--i+d,每次伤害a点生命值。问至少炸几次会消灭所有怪物。
首先贪心原则是:在i处的怪物,最优是放在i+d处,这样可以伤害i+2*d范围内的怪物。
然后会有一个二重循环朴素做法,会超时,利用尺取+差分来优化。
c数组代表已经在某点炸了几次。
首先得到j,即利用此贪心原则所能伤害到的最大位置+1,然后用cj-=need。
c[i+1]+=c[i]。答案累加need。
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int maxn=200000+66;
struct monster
{
ll x,h;
}mon[maxn];
bool cmp(monster a,monster b)
{
return a.x>n>>d>>a;
rep(i,1,n)
{
cin>>mon[i].x>>mon[i].h;
}
sort(mon+1,mon+n+1,cmp);
ll ans=0;
//尺取法,贪心原则:第i点要炸时在i+d点放炸弹
//c数组代表已经炸了多少次
for(int i=1,j=1;i<=n;i++)
{
while(j<=n&&mon[j].x<=mon[i].x+2*d)
j++;//找到不能炸到的
ll need=max((mon[i].h-c[i]*a+a-1)/a,0ll);
c[i]+=need;
c[j]-=need;
c[i+1]+=c[i];
ans+=need;
}
cout<