高弗雷勋爵
这个题很水,但是半个小时都读错题,就很伤了,先把敌人的血量从小到大排序,用一个sum记录我当前已经扣除的血量,如果对于一个敌人,hp高于我的sum,我就看我还需要多少发子弹res,使得sum+res*2>=hp即可,然后杀死一个敌人,答案就加res,我又获得一发子弹(子弹继续伤害暂时理解为奖励获得一发子弹),先别急着sum+=2,先杀死后面我不用奖励的子弹也能杀死的敌人,再将sum+=2即可。
#include
#include
#include
#include
打羽毛球的小爱同学
吉老师出的杭电6425原题(多校9),首先不看a只看b,c,d,因为a无球无拍,对于b,c,d,可以一个人都不用来,初始ans=1,然后b只有拍,从b中任意组合都打不了球,因此ans+=2^b-1,为什么减一,初始化就算了一个人都不用来,因此b个人的组合去掉一个人都不来的情况,同理,c只有球,任意c的组合也打不了球,ans+=2^c-1,d有球有拍,但是d只能来一个人也是不行的,所以ans+=d,两球一拍或者只有一球一拍也不行,所以ans+=(b+d)*(2^c-1)。
#include
using namespace std;
typedef long long ll;
const int maxn=1e7+10;
const int mod=998244353;
int n,m,a,b,c,d;
ll p[maxn];
int main()
{
p[0]=1;
for(int i=1;i
共边三角形
这个题是hdu6447(ccpc网络赛)的升级版,思路一模一样,不过这题的角度排序比较恶心。
分析一下这张图,我们先按照角度k1从小到大排序(三角形顶点和x轴以及原点构成的角),定义角度k2为三角形顶点和x轴以及点(n,0)构成的角度,我们按照k1从小到大处理三角形,先看A,A里面显然没有三角形,d[ A ]答案就是1,接下来看B,因为只有A的k2小于B的k2,d[ B ]=d[ A ]+1=2,看C也是一样,看E也是d[ E ]=d[ A ]+1=2,再看F,发现E和A的k2都小于F,那我们就看d[ A ]和d[ E ]谁大,显然d[ E ]大,那么d[ F ]=d[ E ]+1=3。该题数据小,可以用暴力过(n*n复杂度),若是数据大,可用线段树过(nlogn复杂度),线段树维护区间最大的d[ i ]值。
线段树代码:(很丑陋...)
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=1e5;
int tree[maxn*4];
ll n;
struct node
{
ll x,y;
int id,num;
bool operator<(const node& t)const
{
if(x>n)
{
if(t.x<=n)return false;
return y*(t.x-n)>t.y*(x-n);
}
else
{
if(t.x>n)return true;
return y*(n-t.x)m)res=max(res,query(rs,m+1,r,k));
return res;
}
void update(int o,int l,int r,int k,int v)
{
if(l==r)
{
tree[o]=max(tree[o],v);
return;
}
int ls=o*2,rs=o*2+1,m=(l+r)/2;
if(k<=m)update(ls,l,m,k,v);
else update(rs,m+1,r,k,v);
tree[o]=max(tree[ls],tree[rs]);
}
int main()
{
int k;
while(~scanf("%lld",&n))
{
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
b[i].x=x,b[i].y=y,b[i].id=i;
a[i].x=x,a[i].y=y,a[i].id=i;
}
sort(a+1,a+1+k);
sort(b+1,b+1+k);
int sz=0,tot=0;
b[1].num=++sz;
for(int i=2;i<=k;i++)
if(b[i]==b[i-1])b[i].num=b[i-1].num;
else b[i].num=++sz;
for(int i=1;i<=k;i++)
d[b[i].id]=b[i].num;
memset(tree,0,sizeof(tree));
for(int i=1;i<=k;i++)
{
if(a[i]==a[i-1])
{
V[++tot]=a[i];
int pos=d[a[i].id];
int v=query(1,1,k,pos-1);
V[tot].pos=pos,V[tot].v=v+1;
}
else
{
for(int j=1;j<=tot;j++)
update(1,1,k,V[j].pos,V[j].v);
tot=0;
V[++tot]=a[i];
int pos=d[a[i].id];
int v=query(1,1,k,pos-1);
V[tot].pos=pos,V[tot].v=v+1;
}
}
for(int j=1;j<=tot;j++)
update(1,1,k,V[j].pos,V[j].v);
printf("%d\n",tree[1]);
}
}