• 2020浙大软院预推免机试复盘


    总结:题目很难读,只能靠样例理解,也不知道代码写得对不对,万幸数据不太强。

    A

    给一个多项式的因式分解的形式,比如P=(x-a1)(x-a2)...(x-an),要求出多项式除了x^n之外,其他项的系数。n<=10。

    比如x^2,就是选2项共享一个x,其他项贡献ai乘起来,所以dfs搜一下。

    //
    // Created by zxc on 2020/9/23.
    //
    #include <bits/stdc++.h>
    using namespace std;
    int n;
    int r[15];
    int res[15];
    bool vis[15];
    void dfs(int i,int now,int tar){
        if(i==n+2){
            return;
        }
        if(now==tar){
            int t=1;
            for(int j=1;j<=n;j++){
                if(!vis[j]){
                    t=t*r[j];
                }
            }
            res[tar]+=t;
            return;
        }
        vis[i]=true;
        dfs(i+1,now+1,tar);
        vis[i]=false;
        dfs(i+1,now,tar);
    }
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&r[i]);
            r[i]=-r[i];
        }
        for(int i=n-1;i>=0;i--){
            dfs(1,0,i);
        }
        for(int i=n-1;i>=0;i--){
            printf("%d%c",res[i],i==0?'
    ':' ');
        }
        return 0;
    }
    
    

    B

    给定三个数集,大小是1e4,在三个集合里分别找三个数a,b和c,使得|a-b|+|b-c|+|c-a|最小。

    这题一开始没思路放了,思路一开始不对,一直想着正负正负和大小关系,后来想枚举枚举,就想到枚举中间的数,再一看,发现如果枚举中间的数,那表达式其实就是左右两个数的距离的2倍。

    所以把三个数集排一下序,然后按bac,cab,abc,cba,acb,bca这六种情况,分别枚举中间的值,然后lower_bound找到左右两边最近的一个,再注意判掉一些边界情况。题目说如果有多个输出三元组最大的,可是并没有定义什么是三元组最大的???猜了一下是和最大,就过了。

    代码是我最喜欢的ctrl c+v

    //
    // Created by zxc on 2020/9/23.
    //
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e4+50;
    vector<int> a,b,c;
    int as,bs,cs,x;
    int ans_a,ans_b,ans_c;
    struct node{
        int a,b,c;
        bool operator <(const node& rhs)const{
            return (a+b+c)<(rhs.a+rhs.b+rhs.c);
        }
    };
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d%d%d",&as,&bs,&cs);
        for(int i=0;i<as;i++){
            scanf("%d",&x);
            a.push_back(x);
        }
        for(int i=0;i<bs;i++){
            scanf("%d",&x);
            b.push_back(x);
        }
        for(int i=0;i<cs;i++){
            scanf("%d",&x);
            c.push_back(x);
        }
        sort(a.begin(),a.end());
        sort(b.begin(),b.end());
        sort(c.begin(),c.end());
        int ans=0x3f3f3f3f;
        // cab
        for(int i=0;i<as;i++){
            int mid=a[i];
            int cx=lower_bound(c.begin(),c.end(),mid)-c.begin();
            if(cx==cs){
                cx--;
            }else if(c[cx]!=mid){
                if(cx==0){
                    continue;
                }
                cx--;
            }
            int cc=c[cx];
            int bd=lower_bound(b.begin(),b.end(),mid)-b.begin();
            if(bd==bs){
                continue;
            }
            int bb=b[bd];
            int tmp=2*(bb-cc);
            if(tmp<ans){
                ans=tmp;
                ans_a=mid;
                ans_b=bb;
                ans_c=cc;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={mid,bb,cc};
                if(now<tp){
                    ans_a=mid;
                    ans_b=bb;
                    ans_c=cc;
                }
            }
        }
        // bac
        for(int i=0;i<as;i++){
            int mid=a[i];
            int bx=lower_bound(b.begin(),b.end(),mid)-b.begin();
            if(bx==bs){
                bx--;
            }else if(b[bx]!=mid){
                if(bx==0){
                    continue;
                }
                bx--;
            }
            int bb=b[bx];
            int cd=lower_bound(c.begin(),c.end(),mid)-c.begin();
            if(cd==cs){
                continue;
            }
            int cc=c[cd];
            int tmp=2*(cc-bb);
            if(tmp<ans){
                ans=tmp;
                ans_a=mid;
                ans_b=bb;
                ans_c=cc;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={mid,bb,cc};
                if(now<tp){
                    ans_a=mid;
                    ans_b=bb;
                    ans_c=cc;
                }
            }
        }
        // abc
        for(int i=0;i<bs;i++){
            int mid=b[i];
            int ax=lower_bound(a.begin(),a.end(),mid)-a.begin();
            if(ax==as){
                ax--;
            }else if(a[ax]!=mid){
                if(ax==0){
                    continue;
                }
                ax--;
            }
            int aa=a[ax];
            int cd=lower_bound(c.begin(),c.end(),mid)-c.begin();
            if(cd==cs){
                continue;
            }
            int cc=c[cd];
            int tmp=2*(cc-aa);
            if(tmp<ans){
                ans=tmp;
                ans_a=aa;
                ans_b=mid;
                ans_c=cc;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={aa,mid,cc};
                if(now<tp){
                    ans_a=aa;
                    ans_b=mid;
                    ans_c=cc;
                }
            }
        }
        // cba
        for(int i=0;i<bs;i++){
            int mid=b[i];
            int cx=lower_bound(c.begin(),c.end(),mid)-c.begin();
            if(cx==cs){
                cx--;
            }else if(c[cx]!=mid){
                if(cx==0){
                    continue;
                }
                cx--;
            }
            int cc=c[cx];
            int ad=lower_bound(a.begin(),a.end(),mid)-a.begin();
            if(ad==as){
                continue;
            }
            int aa=a[ad];
            int tmp=2*(aa-cc);
            if(tmp<ans){
                ans=tmp;
                ans_a=aa;
                ans_b=mid;
                ans_c=cc;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={aa,mid,cc};
                if(now<tp){
                    ans_a=aa;
                    ans_b=mid;
                    ans_c=cc;
                }
            }
        }
        // acb
        for(int i=0;i<cs;i++){
            int mid=c[i];
            int ax=lower_bound(a.begin(),a.end(),mid)-a.begin();
            if(ax==as){
                ax--;
            }else if(a[ax]!=mid){
                if(ax==0){
                    continue;
                }
                ax--;
            }
            int aa=a[ax];
            int bd=lower_bound(b.begin(),b.end(),mid)-b.begin();
            if(bd==bs){
                continue;
            }
            int bb=b[bd];
            int tmp=2*(bb-aa);
            if(tmp<ans){
                ans=tmp;
                ans_a=aa;
                ans_b=bb;
                ans_c=mid;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={aa,bb,mid};
                if(now<tp){
                    ans_a=aa;
                    ans_b=bb;
                    ans_c=mid;
                }
            }
        }
        // bca
        for(int i=0;i<cs;i++){
            int mid=c[i];
            int bx=lower_bound(b.begin(),b.end(),mid)-b.begin();
            if(bx==bs){
                bx--;
            }else if(b[bx]!=mid){
                if(bx==0){
                    continue;
                }
                bx--;
            }
            int bb=b[bx];
            int ad=lower_bound(a.begin(),a.end(),mid)-a.begin();
            if(ad==as){
                continue;
            }
            int aa=a[ad];
            int tmp=2*(aa-bb);
            if(tmp<ans){
                ans=tmp;
                ans_a=aa;
                ans_b=bb;
                ans_c=mid;
            }else if(tmp==ans){
                node now={ans_a,ans_b,ans_c};
                node tp={aa,bb,mid};
                if(now<tp){
                    ans_a=aa;
                    ans_b=bb;
                    ans_c=mid;
                }
            }
        }
        printf("MinD(%d, %d, %d) = %d
    ",ans_a,ans_b,ans_c,ans);
        return 0;
    }
    

    C

    题意也是很难读。。。n个人,每个人有一个分数,然后每个人有一个合照,合照上都是同校的队友,然后现在要统计所有学校的总分按从高到低排序,每个学校的id就是最小的那个学生id,分数相同按队员数量从小到大排序,数量相同按id从小到大排序。

    id是4位数,所以不用离散化,就先并查集合并一下,然后暴力枚举全部出现过的id,更新每个学校队伍的最小学生id,以及统计数量和总分,然后去重,排序。最后输出记得要%4d。

    //
    // Created by zxc on 2020/9/23.
    //
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+50;
    int p[N];
    int n,k,id[N],sc[N],x;
    vector<int> fr[N];
    int find(int x){
        return x==p[x]?p[x]:p[x]=find(p[x]);
    }
    int vis[N];
    struct node{
        int scid;
        int allsco;
        int num;
        int fir=true;
        bool operator<(const node& rhs)const{
            if(allsco!=rhs.allsco){
                return allsco>rhs.allsco;
            }else{
                if(num!=rhs.num){
                    return num<rhs.num;
                }else{
                    return scid<rhs.scid;
                }
            }
        }
        bool operator ==(const node& rhs)const{
            return (allsco==rhs.allsco && num==rhs.num && scid==rhs.scid && fir==rhs.fir);
        }
    }ans[N];
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(int i=0;i<=9999;i++){
            p[i]=i;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&id[i]);
            vis[id[i]]=true;
            scanf("%d",&k);
            for(int j=0;j<k;j++){
                scanf("%d",&x);
                vis[x]=true;
                int fa=find(id[i]);
                int fb=find(x);
                fr[id[i]].push_back(x);
                if(fa!=fb){
                    p[fa]=fb;
                }
            }
            scanf("%d",&sc[id[i]]);
        }
        for(int i=0;i<=9999;i++){
            if(!vis[i]){
                continue;
            }
            int fa=find(i);
            ans[fa].allsco+=sc[i];
            ans[fa].num++;
            if(ans[fa].fir){
                ans[fa].scid=i;
                ans[fa].fir=false;
            }else{
                ans[fa].scid=min(ans[fa].scid,i);
            }
        }
        vector<node> v;
        for(int i=0;i<=9999;i++){
            if(!vis[i]){
                continue;
            }
            int fa=find(i);
            v.push_back(ans[fa]);
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        int siz=v.size();
        printf("%d
    ",siz);
        for(int i=0;i<siz;i++){
            printf("%04d %d %d
    ",v[i].scid,v[i].num,v[i].allsco);
        }
        return 0;
    }
    

    D

    题意不知道在讲啥。。。连个中心词coupon都看不懂,估计是优惠还是啥,反正分析样例就是有n个商品,n个级别的优惠,买一个商品可以得到一个优惠(显然是选优惠最高的),同理买同一种的第二个商品就只能选第二档优惠,如果买超过n个同类商品,就没有优惠了。有d美元,问怎么买可以买到最多的商品。

    这题卡了将近一个小时。。。最后灵光一现想到面经里面看过排序几个有序大文件里的数字,就堆里只要放每个文件的一个指针,然后拿完一个就把对应文件的指针移到下一个数。

    所以同理,维护一个堆,先把买每一种商品用第一档优惠真正需要花的钱放堆里,然后拿出最小的,把对应的商品使用第二档优惠的花的钱放进去,以此类推,直到钱不够了。

    //
    // Created by zxc on 2020/9/23.
    //
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+50;
    const int D=1e6+50;
    int n,d;
    int a[N],b[N];
    bool cmp(int x,int y){
        return x>y;
    }
    struct node{
        int i,j,cos;
        bool operator <(const node& rhs)const{
            return cos>rhs.cos;
        }
    };
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&d);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
        }
        sort(a+1,a+1+n,cmp);
        sort(b+1,b+1+n,cmp);
        priority_queue<node> q;
        for(int i=1;i<=n;i++){
            q.push(node{i,1,a[i]-b[1]});
        }
        int ans=0;
        int res=d;
        while(!q.empty()){
            node t=q.top();
            q.pop();
            res-=t.cos;
            if(res<0){
                res+=t.cos;
                break;
            }
            ans++;
            if(t.j+1<=n){
                q.push(node{t.i,t.j+1,a[t.i]-b[t.j+1]});
            }else{
                // 考试时没写上这个,也过了
                q.push(node{t.i,t.j+1,a[t.i]});
            }
        }
        printf("%d %d
    ",ans,res);
    }
    
  • 相关阅读:
    干货分享|安全测试起航之旅
    干货|宏巍软件之Java线程监控之旅
    大数据时代,业务运维驱动下的企业变革
    什么是业务运维,企业如何实现互联网+业务与IT的融合
    不谈业务运维的IT主管早晚被淘汰 这里是10条干货
    详解APM数据采样与端到端
    CTO对话:云端融合下的移动技术创新
    【1111元天天拿!充一送二玩真哒!】双十一任性活动
    引领手机流量营销 嘿嘿流量打造多场景专业服务
    “烧钱补贴”下的O2O该何去何从?
  • 原文地址:https://www.cnblogs.com/zxcoder/p/13724091.html
Copyright © 2020-2023  润新知