GDUT-2016校赛决赛



Problem  A:Krito的讨伐


Problem  B:Sward Art Online

用max1[money]来表示花费money在头盔和首饰上能得到的最优值,故枚举a,枚举b,枚举a[i]+b[j]的a*b种情况。(因为b和a可能有依赖关系)

用max2[money]来表示花费money在单手和双手上能得到的最优值,故枚举c两两相加的c*(c-1)种情况,再枚举d即可

max1,max2都遍历1-m,若max[i]<max[i-1]则应更新max[i]....之后就可以直接求最大的max1[i]+max2[m-i]了.....


AC代码:

#include<iostream>
#include<string.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
#define mem(a,num) memset(a,num,sizeof(a))

int T,m,a,b,c,d;

struct Node
{
    int money;
    int atk;
};

struct Flag
{
    int id;
    int buff;
};

int main()
{
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        Node aa[105],bb[105],cc[105],dd[105];
        int max1[10005],max2[10005];
        Flag b2[105];
        mem(max1,0);
        mem(max2,0);
        cin>>m>>a>>b>>c>>d;
        int num1=0,num2=0;
        for(int i=0;i<a;++i)
        {
            cin>>aa[i].money>>aa[i].atk;
            max1[aa[i].money]=max(max1[aa[i].money],aa[i].atk);
        }
        for(int i=0;i<b;++i)
        {
            cin>>bb[i].money>>bb[i].atk>>b2[i].id>>b2[i].buff;
            max1[bb[i].money]=max(max1[bb[i].money],bb[i].atk);
        }
        for(int i=0;i<c;++i) cin>>cc[i].money>>cc[i].atk;
        for(int i=0;i<d;++i)
        {
            cin>>dd[i].money>>dd[i].atk;
            max2[dd[i].money]=max(max2[dd[i].money],dd[i].atk);
        }
        for(int i=0;i<a;++i)
        for(int j=0;j<b;++j)
        {
            int tmp1=aa[i].money+bb[j].money;
            int tmp2=aa[i].atk+bb[j].atk;
            if(b2[j].id==i) tmp2+=b2[j].buff;
            max1[tmp1]=max(max1[tmp1],tmp2);
        }
        for(int i=0;i<c-1;++i)
        for(int j=i+1;j<c;++j)
        {
            int tmp1=cc[i].money+cc[j].money;
            int tmp2=cc[i].atk+cc[j].atk;
            max2[tmp1]=max(max2[tmp1],tmp2);
        }
        for(int i=1;i<=m;++i)
        {
            if(max1[i]<max1[i-1])
                max1[i]=max1[i-1];
            if(max2[i]<max2[i-1])
                max2[i]=max2[i-1];
        }
        int ans=0;
        for(int i=0;i<=m;++i)
            ans=max(ans,max1[i]+max2[m-i]);
        cout<<ans<<endl;
    }
    return 0;
}


Problem  C:wintermelon的魔界寻路之旅


Problem  D:二叉树的中序遍历

思路:在中序遍历序列中,如果#对应叶子节点,那么相邻的必然是非叶子节点,故只要存在连续的#就可以判定为no了,特判一下只有一个节点的情况.为#就是no了....


Problem  E:积木积水

思路:左右夹逼,如果可以积水必然是高度以左右较小的高度来积水,如果夹逼过程遇到比当前大的,就更新当前值,重新比较左右两端的值,反复如此.....结果记得用long long存


AC代码:

#include<iostream>
using namespace std;
 
typedef long long ll;
 
const int MAXN = 1e6+5;
int a[MAXN];
 
int main()
{
    ios::sync_with_stdio(false);
    int n,T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;++i) cin>>a[i];
        int l=0,r=n-1;
        ll count=0;
        while(l<r)
        {
            int i;
            if(a[l]<a[r])
            {
                for(i=l+1;i<r;++i)
                {
                    if(a[i]>a[l]) break;
                    count+=a[l]-a[i];
                }
                l=i;
            }
            else
            {
                for(i=r-1;i>l;--i)
                {
                    if(a[i]>a[r]) break;
                    count+=a[r]-a[i];
                }
                r=i;
            }
        }
        cout<<count<<endl;
    }
    return 0;
}

Problem  F:我是好人4

1、ai%aj==0  -> 去掉ai

2、DFS+lcm容斥,且lcm>n则return;






你可能感兴趣的:(GDUT-2016校赛决赛)