2015暑假ACM集训结训赛(第一场)(SDUTOJ)

来源:互联网 发布:配音朗读软件 编辑:程序博客网 时间:2024/06/01 21:42

简单写下自己的题解;

1.奇妙23点:

 地址:http://sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=3297

各种爆搜;

示例代码:

#include <bits/stdc++.h>#define LL long long#define INF 0x3f3f3f3fusing namespace std;LL a[12];bool flag[60];bool mark;void DFS(int cnt,LL sum){    if(cnt>4)    {        if(sum==23)            mark=1;        return;    }    int tmp;    for(int i=0; i<5; i++)    {        if(!flag[i])        {            for(int j=0; j<3; j++)            {                tmp=sum;                if(j==0)                {                    flag[i]=1;                    DFS(cnt+1,tmp+=a[i]);                    flag[i]=0;                }                else if(j==1)                {                    flag[i]=1;                    DFS(cnt+1,tmp-=a[i]);                    flag[i]=0;                }                else                {                    flag[i]=1;                    DFS(cnt+1,tmp*=a[i]);                    flag[i]=0;                }                if(mark)                    return;            }             if(mark)            return ;        }    }}int main(){    ios::sync_with_stdio(0);    while(cin>>a[0])    {        mark=0;        memset(flag,0,sizeof(flag));        for(int i=1; i<5; i++)        {            cin>>a[i];        }        for(int i=0; i<5; i++)        {            flag[i]=1;            DFS(1,a[i]);            if(mark)                break;            flag[i]=0;        }        if(mark)            printf("Yes\n");        else            printf("No\n");    }    return 0;} 

2.小新杀怪兽;

嗯好像叫离散化;

#include <bits/stdc++.h>#define LL long long#define INF 0x3f3f3f3fusing namespace std;LL a[1110000];int main(){    int n,m,cnt;    LL u,v,w;    while(scanf("%d",&cnt),cnt)    {        memset(a,0,sizeof(a));        scanf("%d",&n);        for(int i=0;i<n;i++)        {            scanf("%lld%lld%lld",&u,&v,&w);            a[u]+=w;            a[v+1]-=w;        }      LL ans=0;        for(int i=1;i<=cnt;i++)        {          a[i]=a[i-1]+a[i];        }        for(int i=cnt-1;i>=1;i--)        {        a[i]+=a[i+1];        }        scanf("%d",&m);        while(m--)        {            scanf("%lld%lld",&u,&v);            if(a[v]<u)                ans++;        }        cout<<ans<<endl;    }    return 0;}

3.完美字符串:

签到题:

#include <bits/stdc++.h>#define LL long long#define INF 0x3f3f3f3fusing namespace std;int a[128];char s[10010];bool cmp(int x,int y){    return x>y;}int main(){    while(~scanf("%s",s))    {        int len=strlen(s);        memset(a,0,sizeof(a));        for(int i=0;i<len;i++)        {            if(s[i]>='A'&&s[i]<='Z')                 s[i]+=32;            a[s[i]]++;        }        int cnt=26;        LL sum=0;        sort(a,a+128,cmp);        for(int i=0;i<30;i++)        {            sum+=a[i]*cnt;                cnt--;        }        cout<<sum<<endl;    }    return 0;}

4.效率至上

恩线段树;

#include <bits/stdc++.h>#define LL long long#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define INF 0x3f3f3f3fusing namespace std;const int N =5e4+10;int maxn[N<<2];int mm[N<<2];void pushup(int rt){    maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);    mm[rt]=min(mm[rt<<1],mm[rt<<1|1]);}void build(int l,int r,int rt){    if(l==r)    {        scanf("%d",&maxn[rt]);        mm[rt]=maxn[rt];        return;    }    int mid=(l+r)>>1;    build(lson);    build(rson);    pushup(rt);}int Query1(int L,int R,int l,int r,int rt){    if(L<=l&&R>=r)    {        return maxn[rt];    }    int mid=(l+r)>>1;    if(R<=mid)        return Query1(L,R,lson);    else if(L>mid)       return Query1(L,R,rson);    else     return max(Query1(L,mid,lson),Query1(mid+1,R,rson));}int Query2(int L,int R,int l,int r,int rt){    if(L<=l&&R>=r)    {        return mm[rt];    }    int mid=(l+r)>>1;    if(R<=mid)        return Query2(L,R,lson);    else if(L>mid)        return Query2(L,R,rson);    else     return min(Query2(L,mid,lson),Query2(mid+1,R,rson));}int main(){    int m,n;    int u,v;    while(~scanf("%d%d",&n,&m))    {        build(1,n,1);        while(m--)        {            scanf("%d%d",&u,&v);            printf("%d\n",Query1(u,v,1,n,1)-Query2(u,v,1,n,1));        }    }    return 0;}

5.;来发背包开开胃:

“背包”太大,暴力吧;

#include <bits/stdc++.h>#define LL long long#define INF 0x3f3f3f3fusing namespace std;struct node{    LL x,y,z;}que[10];int main(){    LL v,n;    while(~scanf("%lld%lld",&n,&v))    {        for(int i=0;i<3;i++)        {            que[i].x=que[i].y=que[i].z=0;        }        for(int i=0;i<n;i++)        {            scanf("%lld%lld%lld",&que[i].x,&que[i].y,&que[i].z);        }        LL ans=0,tmp;        for(int i=0;i<=que[2].x;i++)        {            for(int j=0;j<=que[1].x;j++)            {                for(int k=0;k<=que[0].x;k++)                {                    tmp=k*que[0].y+j*que[1].y+i*que[2].y;                    if(tmp<=v)                        ans=max(ans,k*que[0].z+j*que[1].z+que[2].z*i);                }            }        }        cout<<ans<<endl;    }    return 0;} 

递归形式:

#include <iostream>#include<bits/stdc++.h>#define LL long longusing namespace std;struct node{    LL x,y,z;}que[4];LL ans;LL n,v;void DFS(int cnt,LL vm,LL sum){    if(cnt>n)    {        ans=max(sum,ans);         return ;    }    for(int i=0;i<=que[cnt].x;i++)    {        if(vm+i*que[cnt].y<=v)        {            DFS(cnt+1,vm+i*que[cnt].y,sum+i*que[cnt].z);        }    }}int main(){     while(~scanf("%lld%lld",&n,&v))     {         memset(que,0,sizeof(que));         ans=0;         for(int i=0;i<n;i++)         {             scanf("%lld%lld%lld",&que[i].x,&que[i].y,&que[i].z);         }         DFS(0,0,0);         printf("%lld\n",ans);     }    return 0;}

6.选课大作战:

并查集不压缩路径是有秩序的;

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<stack>#include<cmath>#include<cctype>#include<set>#include<map>#include<vector>#include<iomanip>#define LL long longusing namespace std;const int  N = 1e5+10;int fa[N];int main(){    int t,n,m;    int u,v;     while(~scanf("%d",&t))     {         memset(fa,-1,sizeof(fa));         while(t--)         {             scanf("%d%d",&n,&m);             bool mark=1;             while(m--)             {                 scanf("%d%d",&u,&v);                 if(!mark)                    continue;                 while(fa[u]!=-1&&fa[u]!=v)                    u=fa[u];                 if(fa[u]==v)                    mark=0;                else                    fa[v]=u;             }         if(!mark)            printf("Wrong\n");         else            printf("Correct\n");         }     }    return 0;}
借助map的并查集;

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<stack>#include<cmath>#include<cctype>#include<set>#include<map>#include<vector>#include<iomanip>#define LL long longusing namespace std;const int  N = 1e5+10;int fa[N];int fint(int x){    return fa[x]!=-1?fa[x]=fint(fa[x]):x;}map<pair<int,int>,bool>M;int main(){    int t,n,m;    int u,v;     while(~scanf("%d",&t))     {         memset(fa,-1,sizeof(fa));         while(t--)         {             M.clear();             scanf("%d%d",&n,&m);             memset(fa,-1,sizeof(fa));             bool mark=1;             while(m--)             {                 scanf("%d%d",&u,&v);                  if(!mark)                    continue;                 if(!M[pair<int,int>(u,v)])                {                    M[pair<int,int>(u,v)]=1;                    u=fint(u);                    v=fint(v);                    if(u==v)                    {                        mark=0;                    }                    fa[u]=v;                }             }         if(!mark)            printf("Wrong\n");         else            printf("Correct\n");         }     }    return 0;}

拓扑:

#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<queue>#include<cstring>using namespace std;const int N = 1e5;struct node{    int v;    int next;}T[6*N+10];int t,n,m;int head[N+10];int a[N+10];int top;bool vis[N+10];void build(int u,int v){    T[top].v=v;    T[top].next=head[u];    head[u]=top++;}void SP(){    memset(vis,0,sizeof(vis));    queue<int>Q;    int cnt=0;    for(int i=1;i<=n;i++)    {        if(a[i]==0)            {                Q.push(i);                cnt++;                vis[i]=1;            }    }    int u,tmp;    while(!Q.empty())    {        u=Q.front();        Q.pop();        for(int i=head[u];i!=-1;i=T[i].next)        {           a[tmp=T[i].v]--;           if(!vis[tmp]&&a[tmp]==0)           {               cnt++;               Q.push(tmp);               if(cnt>=n)                break;           }        }        if(cnt>=n)            break;    }    if(cnt>=n)        printf("Correct\n");    else        printf("Wrong\n");}int main(){    int u,v;    while(~scanf("%d",&t))    {        while(t--)        {            top=0;            memset(a,0,sizeof(a));            memset(head,-1,sizeof(head));            scanf("%d%d",&n,&m);            while(m--)            {                scanf("%d%d",&u,&v);                build(u,v);                a[v]++;            }            SP();        }    }    return 0;} 

7.

质数中的质数;

#include <iostream>#include<bits/stdc++.h>using namespace std;const int  N = 1e6+1e4;int prime[N>>2];bool flag[N];int k;void getprime(){    k=0;    memset(flag,0,sizeof(flag));    for(int i=2;i<N;i++)    {        if(flag[i]==0)        {            prime[++k]=i;        }        for(int j=1;j<=k&&prime[j]*i<N;j++)        {            flag[i*prime[j]]=1;            if(i%prime[j]==0)                break;        }    }}int main(){    getprime();    int n;    while(~scanf("%d",&n))    {        int i;        for(i=1;i<=k;i++)        {            if(prime[i]>=n)                break;        }        for(;i<=k;i++)        {            if(!flag[i])            {                printf("%d\n",prime[i]);                break;            }        }    }    return 0;} 



0 0