zoukankan      html  css  js  c++  java
  • 喵哈哈村的魔法考试 Round #4 (Div.2) 题解

    有任何疑问,可以加我QQ:475517977进行讨论。

    A 喵哈哈村的嘟嘟熊魔法(1)

    题解

    这道题我们只要倒着来做就可以了,因为交换杯子是可逆的,我们倒着去模拟一遍就好了。

    有个函数叫做swap(a,b),表示交换a,b

    #include<bits/stdc++.h>
    using namespace std;
    
    int a[10];
    int x[105],y[105];
    int main(){
        int n;
        while(scanf("%d",&n)!=EOF){
            scanf("%d%d%d",&a[1],&a[2],&a[3]);
            for(int i=0;i<n;i++){
                scanf("%d%d",&x[i],&y[i]);
            }
            for(int i=n-1;i>=0;i--)
                swap(a[x[i]],a[y[i]]);
            for(int i=1;i<=3;i++)
                cout<<a[i]<<" ";
            cout<<endl;
        }
    }
    

    B 喵哈哈村的嘟嘟熊魔法(2)

    题解

    拿一个数组记录一下num[a[i]],表示a[i]出现了多少次,由于里面的数都是正数,所以开一个大数据就行了。

    其实可以用map<int,int>

    面试题的话,你需要构造一个函数f(x)^3=1,这样就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+6;
    map<int,int>H;
    int n,a[maxn];
    int main(){
        while(cin>>n){
            for(int i=0;i<n;i++)
                cin>>a[i];
            H.clear();
            for(int i=0;i<n;i++)
                H[a[i]]++;
            for(int i=0;i<n;i++)
                if(H[a[i]]==1)
                    cout<<a[i]<<endl;
        }
    }
    

    C 喵哈哈村的嘟嘟熊魔法(3)

    题解

    注意数据范围,数据范围只有100,所以每次修改就暴力修改,每次询问,我们就O(100)的去查询就好了。

    其实你写个动态k-th number 树套树也可以

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    int n,m;
    int value[105];
    int a[maxn];
    int main(){
        while(cin>>n>>m){
            memset(value,0,sizeof(value));
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                value[a[i]]++;
            }
            for(int i=0;i<m;i++){
                int op;
                scanf("%d",&op);
                if(op==1){
                    int x,y;
                    scanf("%d%d",&x,&y);
                    value[a[x]]--;
                    a[x]=y;
                    value[a[x]]++;
                }
                else{
                    int num = 2;
                    for(int j=100;j>=1;j--){
                        if(value[j]>=num){
                            cout<<j<<endl;
                            break;
                        }else{
                            num-=value[j];
                        }
                    }
                }
            }
        }
    }
    

    D 喵哈哈村的嘟嘟熊魔法(4)

    题解

    如果全是正数的话,那么我们two pointers就好了。

    但是有正有负怎么办呢,我们枚举中间的mid,然后判断左右是否存在l和r分界线就好了。

    左分界线需要满足prefix[l-1]=prefix[mid-1]-prefix[l],移项可以得到prefix[l]+prefix[l-1]=prefix[mid-1]

    用一个set判断有没有就可以了。

    但是这样做并不能知道左边的和是多少,所以你的set里面应该还带一个现在的和是多少,然后左右再check一下就好了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    set<pair<long long,long long> >S;
    long long a[maxn],b[maxn];
    set<long long> ans[maxn];
    int n,flag[maxn];
    int main(){
        while(cin>>n){
            for(int i=0;i<n;i++){
                cin>>a[i];
            }
            b[0]=a[0];
            for(int i=1;i<n;i++)
                b[i]=a[i]+b[i-1];
            for(int i=0;i<n;i++)
            {
                flag[i]=0;
                ans[i].clear();
            }
            S.clear();
            for(int i=3;i<n;i++){
                S.insert(make_pair(b[i-3]+b[i-2],b[i-2]));
                set<pair<long long,long long> >::iterator s = S.lower_bound(make_pair(b[i-1],-1000000LL));
                while(s!=S.end()&&(*s).first==b[i-1]){
                    flag[i]=1;
                    ans[i].insert(b[i-1]-(*s).second);
                    s++;
                }
            }
            S.clear();
            b[n-1]=a[n-1];
            for(int i=n-2;i>=0;i--){
                b[i]=a[i]+b[i+1];
            }
            int Flag = 0;
            for(int i=n-4;i>=0;i--){
                S.insert(make_pair(b[i+3]+b[i+2],b[i+2]));
                set<pair<long long,long long> >::iterator s = S.lower_bound(make_pair(b[i+1],-1000000LL));
                while((s!=S.end()&&(*s).first==b[i+1])){
                    if(ans[i].find(b[i+1]-(*s).second)!=ans[i].end()&&flag[i]){
                        Flag = 1;
                    }
                    s++;
                }
                if(Flag)break;
            }
            if(Flag == 1){
                cout<<"Yes"<<endl;
            }else{
                cout<<"No"<<endl;
            }
        }
    }
    

    E 喵哈哈村的嘟嘟熊魔法(5)

    一道简单的网络流,如果你会网络流,这道题就是傻逼题。

    否则GG

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int oo=2000000000;
    struct nod{
    int from,con,pre,c,v,flow,rever;
    }edge[100000];
    int num[100000],dist[100000],indexs[100000],now[100000],pos[100000],use[100000],lists[1100000],from[100000];
    int ans,p,s,t,nexts,n,m,i,j,all,ti[200][200];
    void build(int a,int b,int c,int v)
    {
        p++;
        edge[p].from=a;
        edge[p].con=b;
        edge[p].pre=pos[a];
        edge[p].c=c;
        edge[p].v=v;
        edge[p].rever=p+1;
        pos[a]=p;
    
        p++;
        edge[p].from=b;
        edge[p].con=a;
        edge[p].pre=pos[b];
        edge[p].c=c;
        edge[p].flow=c;
        edge[p].v=-v;
        edge[p].rever=p-1;
        pos[b]=p;
    }
    
    void spfas()
    {
        int w,k,l,r,j;
        for (j=i+n+m+2;j>=1;j--) dist[j]=oo;
        dist[s]=0;
        l=1; r=1;  lists[1]=s; use[s]=1;
        while (l<=r)
        {
            k=lists[l];
            for (w=pos[k];w;w=edge[w].pre)
            if (edge[w].c!=edge[w].flow && dist[edge[w].con]>dist[k]+edge[w].v)
            {
                dist[edge[w].con]=dist[k]+edge[w].v;
                from[edge[w].con]=w;
                if (use[edge[w].con]==0)
                {
                    use[edge[w].con]=1;
                    lists[++r]=edge[w].con;
                }
            }
            l++;
            use[k]=0;
        }
        k=t;
        while (k!=s)
        {
            if (edge[from[k]].from==s) nexts=indexs[k];
            ans+=edge[from[k]].v;
            edge[edge[from[k]].rever].flow--;
            edge[from[k]].flow++;
            k=edge[from[k]].from;
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++) scanf("%d",&num[i]),all+=num[i];
        for (i=1;i<=n;i++)
            for (j=1;j<=m;j++)
                scanf("%d",&ti[i][j]);
        s=1; t=2;
        for (i=1;i<=n;i++) build(m+2+i,t,num[i],0);
        for (i=1;i<=m;i++)
        {
            now[i]=1;
            build(s,i+2,1,0);
            indexs[i+2]=i;
            for (j=1;j<=n;j++) build(i+2,m+2+j,1,ti[j][i]);
        }
        for (i=1;i<=all;i++)
        {
            spfas();
            now[nexts]++; indexs[n+m+2+i]=nexts;
            build(s,n+m+2+i,1,0);
            for (j=1;j<=n;j++) build(n+m+2+i,m+2+j,1,now[nexts]*ti[j][nexts]);
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    linux驱动程序设计的硬件基础,王明学learn
    linux设备驱动概述,王明学learn
    应用程序调试工具gdb,王明学learn
    usb设备驱动描述,王明学learn
    OK6410移植madplay播放器,王明学learn
    bootstrap使用入门(bootstrap4.2.1版本)
    IntelliJ Idea 常用快捷键列表
    javaFX 多窗口编程
    Spring Boot框架入门教程(快速学习版)
    BindingNavigator 控件
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6505271.html
Copyright © 2011-2022 走看看