前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ACM校赛网络赛部分题解

ACM校赛网络赛部分题解

作者头像
triplebee
发布2018-01-12 15:22:36
5940
发布2018-01-12 15:22:36
举报

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

自动售货机

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

代码语言:javascript
复制
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
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不到,我的锅。

代码语言:javascript
复制
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
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<string,int> 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<<n<<endl;
        }
        bool flag=false;
        for(int i=1;i<cnt;i++)
        {
            for(int j=1;j<cnt;j++)
            {
                if(in[j]==0 && !vis[j])
                {
                    vis[j]=1;
                    flag=true;
                    for(int k=1;k<cnt;k++)
                        if(g[j][k])
                            in[k]--;
                    break;
                }
            }
            if(flag==false)
                break;
            flag=false;
        }
        scanf("%d",&m);
        int num=0;
        for(int i=0;i<m;i++)
        {
            string a;
            cin>>a;
            if(mp[a]>0 && vis[mp[a]]) num++;
        }
        if(1.0*num/m>0.7)
        cout<<"Excelsior!"<<endl;
        else
        cout<<"KSS have a dream!"<<endl;
    }
    return 0;
}

KSS金牌梦2 

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

代码语言:javascript
复制
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<time.h>
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<b.d;
}
bool cmp2(node a,node b)
{
    return a.l<b.l;
}
void pushup(int now)
{
    tree[now].cnt=0;
    tree[now].val=0;
    if(tree[now].flag[0]!=-1)
    {
        tree[now].cnt+=tree[tree[now].flag[0]].cnt;
        tree[now].val+=tree[tree[now].flag[0]].val;
    }
    if(tree[now].flag[1]!=-1)
    {
        tree[now].cnt+=tree[tree[now].flag[1]].cnt;
        tree[now].val+=tree[tree[now].flag[1]].val;
    }
}
int build(int l,int r)
{
    int now=pos++;
    tree[now].l=l;
    tree[now].r=r;
    tree[now].cnt=tree[now].val=0;
    tree[now].flag[0]=tree[now].flag[1]=-1;
    if(l==r)
        return now;
    int mid=(l+r)>>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<m;i++)
            scanf("%d%d%d%d",&in2[i].x,&in2[i].a,&in2[i].b,&in2[i].c);
        sort(in+1,in+num,cmp1);
        int cnt=0;
        in[num].d=-1;
        for(int i=1;i<num;i++)
            if(in[i].d!=in[i+1].d)
                in[i].val=cnt++;
            else
                in[i].val=cnt;
        sort(in+1,in+num,cmp2);
        root[0]=build(0,cnt-1);
        for(int i=1;i<num;i++)
            root[i]=update(0,cnt-1,in[i].val,in[i].d,root[i-1],in[i].flag);
        for(int i=0;i<m;i++)
        {
                int low=1,high=n*2;
                int ans1=0;
                while(low<=high)
                {
                    int mid=(low+high)>>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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-03-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档