USACO 3.1

本文提供洛谷平台上的经典算法题目解决方案,包括最短网络Agri-Net的Kruskal算法实现,总分ScoreInflation与邮票Stamps的完全背包问题,丑数HumbleNumbers的广搜算法,以及联系Contact的高级模拟算法。

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

洛谷 1546 最短网络 Agri-Net

代码(kruskal)

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
struct node{int x,y,w;}e[12500001];
int f[5001],n,nod,ans,m;
inline int in(){
    int ans=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
} 
void add(int i,int j,int k){e[++m].x=i; e[m].y=j; e[m].w=k;}
bool cmp(node u,node v){return u.w<v.w;}
int find(int u){return (f[u]==u)?u:f[u]=find(f[u]);} 
int main(){
    n=in();
    for (int i=1;i<=n;i++) f[i]=i;
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    if (i<j) add(i,j,in()); else in();
    stable_sort(e+1,e+1+m,cmp);
    while (--n){
    int k1=find(e[++nod].x);
    int k2=find(e[nod].y);
    if (k1!=k2) f[k1]=k2,ans+=e[nod].w; else n++;
    }
    printf("%d",ans);
    return 0;
}

洛谷 2722 总分 Score Inflation

代码(完全背包)

#include <cstdio>
#define rr register
#define max(a,b) ((a)>(b))?(a):(b)
using namespace std;
int n,m,f[10001];
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (c<48||c>57) c=getchar();
    while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
    return ans;
}
signed main(){
    m=iut(); n=iut();
    for (rr int i=1,c,w;i<=n;++i){
        c=iut(); w=iut();
        for (rr int j=w;j<=m;++j)
            f[j]=max(f[j],f[j-w]+c);
    }
    printf("%d\n",f[m]);
    return 0;
}

洛谷 2723 丑数 Humble Numbers

代码(广搜)

#include <cstdio>
using namespace std;
int sum[100001],ugly[100001],a[101],k,n,min;
int main(){
    scanf("%d%d",&k,&n); ugly[0]=1; n++;
    for (int i=1;i<=k;i++) scanf("%d",&a[i]);
    for (int i=1;i<=n;min=2147483647,i++){
        for (int j=1;j<=k;j++){
            while (a[j]*ugly[sum[j]]<=ugly[i-1]) sum[j]++;
            if (a[j]*ugly[sum[j]]<min) min=a[j]*ugly[sum[j]];
        }
        ugly[i]=min;
    }
    printf("%d",ugly[n]); return 0;
}

洛谷 2724 联系 Contact

代码(有难度的模拟)

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstring>
#define rr register
using namespace std;
struct rec{
    int x,y,z;
    bool operator <(const rec &t)const{
        return x>t.x||(x==t.x&&(z<t.z||(z==t.z&&y<t.y)));
    }
}a[4096];
char c,s[200001];
inline void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
inline void prin(int x,int y){
    if (x) prin(x>>1,y-1),putchar(48+(x&1));
        else while (y>0) putchar(48),--y;
}
int main(){
    rr int A,B,n,m=0,cnt=0; 
    scanf("%d%d%d",&A,&B,&n);
    while ((c=getchar())!=EOF)
        if (isdigit(c)) s[++m]=c;
    B=B>m?m:B;
    for (rr int i=1,k=0;i<=B;++i){
        k=k<<1|(s[i]^48);
        if (i>=A){
            rr int t=(1<<i)-1,v[4096];
            memset(v,0,sizeof(v));
            v[k]=1; rr int k1=k;
            for (rr int j=i+1;j<=m;++j)
                ++v[k1=(k1<<1|(s[j]^48))&t];
            for (rr int j=0;j<=t;++j)
                if (v[j]) a[++cnt]=(rec){v[j],j,i};
        }
    }
    sort(a+1,a+1+cnt);
    for (rr int i=1,j=1;i<=n&&j<=cnt;++i){
        print(a[j].x); putchar(10); rr int ente=1;
        while (a[j+1].x==a[j].x){
            prin(a[j].y,a[j].z);
            if (ente==6) putchar(10),ente=0;
            else putchar(32); ++j,++ente;
        }
        prin(a[j].y,a[j].z); ++j;
        if (ente) putchar(10);
    }
    return 0;
}

洛谷 2725 邮票 Stamps

代码(完全背包)

/*
ID:lemondi1
LANG:C++
TASK:stamps
*/
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
#define min(a,b) ((a)<(b))?(a):(b)
using namespace std;
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
int f[2000001],k=iut(),x;
int main(){
    //freopen("stamps.in","r",stdin);
    //freopen("stamps.out","w",stdout);
    fill(f+1,f+1+2000000,20000);
    for (rr int n=iut();n;--n){
        x=iut();
        for (rr int j=x;j<2000001;++j)
        if (f[j-x]<k) f[j]=min(f[j],f[j-x]+1);
    }
    for (rr int i=1;i<2000001;++i)
    if (f[i]>k) return !printf("%d\n",i-1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值