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

本文分享了多种编程算法及技巧,包括搜索、离散化、背包问题、并查集、拓扑排序、质数筛选等,覆盖了从简单到复杂的多个层面,旨在提升读者的算法解决能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单写下自己的题解;

1.奇妙23点:

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

各种爆搜;

示例代码:

#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using 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 0x3f3f3f3f
using 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 0x3f3f3f3f
using 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 0x3f3f3f3f
using 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 0x3f3f3f3f
using 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 long
using 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 long
using 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 long
using 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;
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值