百度之星2018资格赛伪题解(D题做不来啊QwQ)

本文深入探讨了算法与数据结构的核心概念,包括排序算法、动态规划、哈希算法等,详细介绍了各种算法的实现原理及应用实例。同时,文章还涵盖了数据结构的基本类型和高级应用,如二叉树、队列、链表等,旨在为读者提供全面的算法与数据结构知识体系。

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

AB傻逼题

A枚举子集

B维护前缀和

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+100;
int n,m,k;
char s[2001][2001];
int f[3000]={};
int bin[15];
int main(){
//    freopen("a.in","r",stdin);
    bin[0]=1;
    for(int i=1;i<=12;i++)bin[i]=bin[i-1]*2;
    int Cas,Id=0;
    scanf("%d",&Cas);
    while(Cas--){
        int ans=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]);
        }
        int Mx=(1<<m)-1;
        for(int i=1;i<=Mx;i++){
            int ret=0;
            memset(f,0,sizeof(f));
            for(int j=1;j<=n;j++){
                int sum=0;
                for(int k=0;k<m;k++){
                    if(!(i&(1<<k)))continue;
                    if(s[j][k]=='A')sum+=bin[k];
                }    
//                cout<<ret<<" "<<f[sum]<<'\n';
                ret+=(j-f[sum]-1);            
                f[sum]++;
            }
//            cout<<ret<<'\n';
            if(ret>=k)ans++;
        }
        cout<<"Case #"<<(++Id)<<": "<<ans<<'\n';
    }
}

 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1000;
int n,Q,T;
char s[N];
int A[N][26];
int main(){
    int Cas,Id=0;
    scanf("%d",&Cas);
    while(Cas--){
        int n,q;
        scanf("%d%d",&n,&q);
        scanf("%s",s+1);
        memset(A,0,sizeof(A));
        for(int i=1;i<=n;i++){
            A[i][s[i]-'A']=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<26;j++){
                A[i][j]=A[i-1][j]+A[i][j];
            }
        }
        cout<<"Case #"<<(++Id)<<":"<<'\n';
        while(q--){
            int l,r;
            scanf("%d%d",&l,&r);
            for(int i=0;i<26;i++){
                if(A[r][i]-A[l-1][i]){
                    cout<<(A[r][i]-A[l-1][i])<<'\n';
                    break;
                }
            }
        }
    }
}

 

C有点难啊:

考虑费用流模型:S-X流 INF,费1 Y-T 流INF 费1 中间正常连边

TLE。

所以KM

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn = 2e2 + 10, inf = 0x3f3f3f3f;
typedef long long ll;

int T, n, w[maxn][maxn], dx[maxn], dy[maxn], slack[maxn], visx[maxn], visy[maxn], l[maxn], r[maxn], pre[maxn];

void bfs(int u) {
    queue<int> Q; Q.push(u);
    visx[u] = 1;
    while (1) {
        while (!Q.empty()) {
            int x = Q.front(); Q.pop();
            for (int y = 1; y <= n; y++) {
                int dif = dx[x] + dy[y] - w[x][y];
                if (!visy[y] && dif <= slack[y]) {
                    pre[y] = x;
                    if (!dif) {
                        if (!l[y]) {
                            for (; y; l[y] = pre[y], swap(y, r[pre[y]]));
                            return;
                        } else {
                            visx[l[y]] = visy[y] = 1;
                            Q.push(l[y]);
                        }
                    } else {
                        slack[y] = dif;
                    }
                }
            }
        }
        int cmp = inf;
        for (int i = 1; i <= n; i++) {
            if (!visy[i] && slack[i] <= cmp) {
                u = i, cmp = slack[i];
            }
        }
        for (int i = 1; i <= n; i++) {
            if (visx[i]) dx[i] -= cmp;
            if (visy[i]) dy[i] += cmp;
            else slack[i] -= cmp;
        }
        if (!l[u]) {
            for (; u; l[u] = pre[u], swap(u, r[pre[u]]));
            return;
        } else {
            visx[l[u]] = visy[u] = 1;
            Q.push(l[u]);
        }
    }
}

void km() {
    for (int i = 1; i <= n; i++) {
        memset(visx, 0, sizeof visx);
        memset(visy, 0, sizeof visy);
        memset(slack, 0x3f, sizeof slack);
        bfs(i);
    }
}
void Pre(){
    memset(dx, 0, sizeof dx);
    memset(dy, 0, sizeof dy);
    memset(l, 0, sizeof l);
    memset(r, 0, sizeof r);
    memset(pre, 0, sizeof pre);    
}
int main() {
//    freopen("c.in","r",stdin);
    int Id=0;
    scanf("%d", &T);
    while(T--){
        Pre(); 
        cout<<"Case #"<<++Id<<": ";
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%d", &w[i][j]), w[i][j] = -w[i][j];
                dx[i] = max(dx[i], w[i][j]);
            }
        }
        km();
        ll ans = 0;
        for (int i = 1; i <= n; i++) ans += -dx[i] - dy[i];
        cout<<ans<<'\n';
    }
    return 0;
}

 

E题因为随机化,直接暴力就好了

#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long 
#define pb push_back
#define inf 0x3f3f3f3f
inline void read(int &x){
    x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
int mod=1e9+7;
int a[10010],N,M;
int C[10010],ans[10010],f[2][10010];
struct BIT{
    inline int lowbit(int x){
        return x&(-x);
    };
    inline void update(int x,int val){
        while(x<=N){
            C[x]+=val;
            C[x]%=mod;
            x+=lowbit(x);
        }
    }
    inline int Query(int x){
           int ret=0;
        while(x){
            ret=(ret+C[x])%mod;
            x-=lowbit(x);
        }
        return ret;
    }    
}T;

int n,m;
INT main(){
//    freopen("e.in","r",stdin);
    int Cas,Id=0;
    read(Cas);
    while(Cas--){
        read(n); 
        N=n;
        for(int i=1;i<=n;++i) read(a[i]),f[0][i]=1;
        ans[1]=n;
        int cur=1;
        for(int len=2;len<=n;++len){
            ans[len]=0;
            if(ans[len-1]==0) continue;
            for(int i=1;i<=n;++i){
                int tmp=T.Query(a[i]-1);
                ans[len]+=tmp;
                T.update(a[i],f[cur^1][i]);
                f[cur][i]=tmp;

            }
            for(int i=1;i<=n;++i)C[i]=0;
            cur^=1;
        }
        cout<<"Case #"<<++Id<<": ";
        for(int i=1;i<=n-1;++i) cout<<ans[i]%mod<<" ";
        cout<<ans[n];
        cout<<'\n';
    }
    return 0;
}
BestCoder Contest System 2.0

 

F题两颗最小生成树暴力加边,打擂台输出答案

#include<bits/stdc++.h>
using namespace std;
const int N=301;
const int INF=1e9+7;
inline void read(int &x){
    x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
struct Front_star{
    int u,v,w,c,use,nxt;
}e[N*2]; 
int cnt=0;
int first[N]={};
void add(int u,int v,int w,int c){
    cnt++;
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].c=c;
    e[cnt].nxt=first[u];
    first[u]=cnt;
}
bool cmp(Front_star A,Front_star B){
    return A.w<B.w;
}
int fa[N]={};
int ans[N]={};
int n,m;
inline int getfa(int x){
    if(fa[x]==x)return x;
    else return fa[x]=getfa(fa[x]);
}
inline void Union(int x,int y){
    int dx=getfa(x);
    int dy=getfa(y);
    fa[dx]=dy;
}
void Kruskal(int no){
    int ecnt=0;
    int sum=0;
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        e[i].use=0;
        if(e[i].c==no)continue;        
        int u=e[i].u;
        int v=e[i].v;
        if(getfa(u)!=getfa(v)){            
            Union(u,v);
            ecnt++;
            sum+=e[i].w;
            e[i].use=1;
        }
    }
//    cout<<ecnt<<"--"<<'\n';
    if(ecnt<n-1)return;
    if(ans[n-1]==-1)ans[n-1]=sum;
    else ans[n-1]=min(ans[n-1],sum);
    int l=1;
//    cout<<sum<<'\n';
    for(int i=1;i<=m;i++){
        if(e[i].use)continue;
        sum+=e[i].w;
        ecnt++;
//        cout<<ecnt<<" "<<sum<<'\n';
        if(ans[ecnt]==-1)ans[ecnt]=sum;
        else ans[ecnt]=min(ans[ecnt],sum);
    }
//    cout<<'\n';
}
void Pre(){
    memset(first,0,sizeof(first));
    cnt=0;
}
int main(){
//    freopen("f.in","r",stdin);
    int Cas,Id=0;
    read(Cas);
    while(Cas--){
        cout<<"Case #"<<++Id<<":"<<'\n';
        Pre();
        read(n);
        read(m);
        for(int i=1;i<=m;i++){
            int u,v,w,c;
            char ch[3];
            read(u);
            read(v);
            read(w);
            scanf("%s",ch);
//            cout<<u<<" "<<v<<" "<<w<<" "<<ch<<'\n';
            if(ch[0]=='R'){
                c=1;
            }
            if(ch[0]=='B'){
                c=2;
            }
            if(ch[0]=='G'){
                c=3;
            }            
            add(u,v,w,c);
        }
        sort(e+1,e+1+cnt,cmp);
        for(int i=1;i<=m;i++)ans[i]=-1;
        Kruskal(1);
        Kruskal(2);
        for(int i=1;i<=m;i++){
            cout<<ans[i]<<'\n';
        }
    }
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值