小米全国高校编程大赛 正式赛题解

高弗雷勋爵

这个题很水,但是半个小时都读错题,就很伤了,先把敌人的血量从小到大排序,用一个sum记录我当前已经扣除的血量,如果对于一个敌人,hp高于我的sum,我就看我还需要多少发子弹res,使得sum+res*2>=hp即可,然后杀死一个敌人,答案就加res,我又获得一发子弹(子弹继续伤害暂时理解为奖励获得一发子弹),先别急着sum+=2,先杀死后面我不用奖励的子弹也能杀死的敌人,再将sum+=2即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=1e5;
int a[maxn];
int main()
{
	char c;
	while(~scanf("%d",&a[1]))
	{
		int tot=1;
		while(~scanf("%c",&c)&&c!='\n')
		{
			tot++;
			scanf("%d",&a[tot]);
		}
		int ans=0;
		sort(a+1,a+1+tot);
		int sum=0,flag=0;
		for(int i=1;i<=tot;i++)
		{
			if(a[i]<=sum)continue;//不用奖励的子弹也能杀死 
			if(flag)sum+=2,flag=0;//用奖励的子弹 
			if(a[i]<=sum)//奖励的子弹把敌人杀死 
			{
				flag=1;//标记是否有奖励的子弹 
				continue;
			}
			int t=(a[i]-sum);
			int res=t/2;
			if(t%2)res++;
			sum+=res*2;
			flag=1;
			ans+=res;
		}
		printf("%d\n",ans);
	}
}

打羽毛球的小爱同学

吉老师出的杭电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网络赛)的升级版,思路一模一样,不过这题的角度排序比较恶心。

小米全国高校编程大赛 正式赛题解_第1张图片

分析一下这张图,我们先按照角度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]);
	}
}

 

你可能感兴趣的:(比赛----其他比赛题解)