ACM校赛网络赛部分题解

这次网络赛我共出了三题,现给出题解

自动售货机

由于测试样例很多,每次都计算会超时,所以要打表,递推方程为dp[i][j]=dp[i-1][j]+dp[i-1][j-1];注意优化剪枝,在dp循环过程中如果不剪枝,实打实的2000*1000也是会超时的。

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int dp[2005][1005];
const int mod=(1e9+7);
int main()
{
    //freopen("in3.txt","r",stdin);
    //freopen("out3.txt","w",stdout);
    dp[1][0]=1;
    for(int i=2;i<=2000;i++)
    {
        dp[i][0]=1;
        int len=i/2;
        for(int j=1;j<=len;j++)
        {
            dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]);
            if(dp[i][j]>=mod)
            dp[i][j]%=mod;
        }
    }
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        printf("%d\n",dp[n+m][m]);
    }
    return 0;
}
 

KSS金牌梦1

map离散化+变化的拓扑排序,时限比较紧,实在没想到OJ运行速度如此慢,本机上1s不到,我的锅。

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=505;
int g[MAXN][MAXN],in[MAXN];
bool vis[MAXN];
int main()
{
    //freopen("in1.txt","r",stdin);
    int n,m,cnt;
    while(~scanf("%d",&n))
    {
        map mp;
        cnt=1;
        memset(g,0,sizeof(g));
        memset(in,0,sizeof(in));
        memset(vis,false,sizeof(vis));
        while(n--)
        {
            char a[50],b[50];
            //string a,b;
            scanf("%s%s",a,b);
            if(mp[a]==0)mp[a]=cnt++;
            if(mp[b]==0)mp[b]=cnt++;
            g[mp[b]][mp[a]]=1;
            in[mp[a]]++;//cout<>a;
            if(mp[a]>0 && vis[mp[a]]) num++;
        }
        if(1.0*num/m>0.7)
        cout<<"Excelsior!"<


KSS金牌梦2 

离线存储,按距离排序,加入主席树,维护区间和与覆盖次数两个属性,二分位置查询得出结果,WA点很多很多很多很多,又是我的锅。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=100005;
struct node
{
    int l,d,val,flag;
}in[MAXN<<1];
struct node1
{
    int x,a,b,c;
}in2[MAXN];
struct tree
{
    int l,r,cnt,flag[2];
    long long val;
}tree[MAXN*35];
int root[MAXN<<1],pos;
bool cmp1(node a,node b)
{
    return a.d>1;
    tree[now].flag[0]=build(l,mid);
    tree[now].flag[1]=build(mid+1,r);
    return now;
}
int update(int l,int r,int v,int v1,int pre,int flag)
{
    int now=pos++;
    tree[now].l=l;
    tree[now].r=r;
    tree[now].flag[0]=tree[pre].flag[0];
    tree[now].flag[1]=tree[pre].flag[1];
    tree[now].cnt=tree[pre].cnt;
    tree[now].val=tree[pre].val;
    if(l==r)
    {
        if(flag)
        {
            tree[now].cnt--;
            tree[now].val-=v1;
        }
        else
        {
            tree[now].cnt++;
            tree[now].val+=v1;
        }
        return now;
    }
    int mid=(l+r)>>1;
    if(v<=mid)
        tree[now].flag[0]=update(l,mid,v,v1,tree[pre].flag[0],flag);
    else
        tree[now].flag[1]=update(mid+1,r,v,v1,tree[pre].flag[1],flag);
    pushup(now);
    return now;
}
long long query(int l,int r,int now,long long k)
{
    if(l==r)
    {
            if(tree[now].cnt==0)
                return 0;
            return tree[now].val/tree[now].cnt*k;
    }
    int mid=(l+r)>>1;
    long long ans=0;
    if(k<=tree[tree[now].flag[0]].cnt)
        ans+=query(l,mid,tree[now].flag[0],k);
    else
        ans+=tree[tree[now].flag[0]].val+query(mid+1,r,tree[now].flag[1],k-=tree[tree[now].flag[0]].cnt);
    return ans;
}
int main()
{
    //freopen("in2.txt","r",stdin);
    //freopen("out2.txt","w",stdout);
    int n,m,x,p;
    while(~scanf("%d%d%d%d",&n,&m,&x,&p))
    {
        long long prescore=1;
        pos=0;
        int l,r,d,num=1;
        for(int i=1;i<=n;i++)
        {
                scanf("%d%d%d",&l,&r,&d);
                in[num].l=l;
                in[num].d=d;
                in[num++].flag=0;
                in[num].l=r+1;
                in[num].d=d;
                in[num++].flag=1;
        }
        for(int i=0;i>1;
                    if(in[mid].l<=in2[i].x)
                    {
                        ans1=mid;
                        low=mid+1;
                    }
                    else
                        high=mid-1;
                }
                long long nowk=((long long)in2[i].a*prescore+(long long)in2[i].b)%(long long)in2[i].c;
                int flag=0;
                if(prescore>p)
                    flag=1;
                if(ans1)
                {
                    if(nowk>=tree[root[ans1]].cnt)
                    {
                        prescore=(tree[root[ans1]].val);
                        if(flag)
                        prescore*=2;
                    }
                    else
                    {
                        prescore=query(0,cnt-1,root[ans1],nowk);
                        if(flag)
                        prescore*=2;
                    }
                }
                else
                    prescore=0;
                printf("%I64d\n",prescore);
        }
    }
    return 0;
}




你可能感兴趣的:(资料,ACM竞赛算法)