zoukankan      html  css  js  c++  java
  • 2018北大计算机学科夏令营机试题目

    2018北大计算机学科夏令营机试题目#

    题目链接
    密码依然是fighting!

    百练上北大夏令营的机试题目,全部拉到Virtual judge了 ,给我的感觉是2019的夏令营题目比2018难了一大截。不知道是偶然还是趋势。

    A - 计算两个日期之间的天数

    题目大意:计算两个日期差
    题解:模拟水题,我用的是日期相减。没有写函数,导致中间一个变量用错了,Wa 2,绝了。以后还是多封装函数,不要写复制重复代码,就不贴代码了。

    B - 回文子串

    题目大意:
    暴力找回文串
    题解:
    O(n^3)暴力即可

    #include <iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<cmath>
    using namespace std;
    string str;
    bool is_ok(int i,int j){
        while(str[i]==str[j]){
            i++;
            j--;
            if(j<=i)return 1;
        }
        return 0;
    }
    int main()
    {
        cin>>str;
        int n=str.length();
        for(int i=2;i<=n;i++){
            for(int j=0;j<n;j++){
                    int ed=i+j-1;
                if(ed<n){
                    if(is_ok(j,ed)){
                        for(int k=j;k<=ed;k++){
                            cout<<str[k];
                        }
                        cout<<endl;
                    }
                }
            }
        }
        return 0;
    }
    

    C - The Die Is Cast

    题目大意:
    双层联通块
    题解:
    不知道网上题解怎么写的。我是找到第一层联通快,然后找第二层联通快。写了两个DFS,代码冗长。

    #include <iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<vector>
    #include<cmath>
    using namespace std;
    char maze[55][55];
    char temp[55][55];
    char a[55][55];
    bool vis[55][55];
    bool vis2[55][55];
    bool cur[55][55];
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    int w,h;
    bool in(int x,int y){
        if(x>=0&&x<h&&y>=0&&y<w)return 1;
        return 0;
    }
    void dfs2(int i,int j){
         vis2[i][j]=1;
         for(int ii=0;ii<4;ii++){
            int x=i+dx[ii];
            int y=j+dy[ii];
            if(in(x,y)&&!vis2[x][y]&&temp[x][y]=='X'){
               dfs2(x,y);
            }
        }
    }
    vector<int>ve;
    void gao(){
        memset(vis2,0,sizeof vis2);
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                temp[i][j]=maze[i][j];
                if(temp[i][j]=='X'&&cur[i][j]==0)
                    temp[i][j]='.';
            }
        }
        int cnt=0;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(temp[i][j]=='X'&&!vis2[i][j]){
                    dfs2(i,j);
                    cnt++;
                }
            }
        }
        ve.push_back(cnt);
    
    }
    void dfs(int i,int j){
        vis[i][j]=1;
        cur[i][j]=1;
        for(int ii=0;ii<4;ii++){
            int x=i+dx[ii];
            int y=j+dy[ii];
            if(in(x,y)&&!vis[x][y]&&(maze[x][y]=='X'||maze[x][y]=='*')){
                dfs(x,y);
            }
        }
    }
    int main()
    {
        int   T=0;
        while(cin>>w>>h&&w!=0){
            cout<<"Throw "<<++T<<endl;
            ve.clear();
            memset(vis,0,sizeof(vis));
            for(int i=0;i<h;i++)
                for(int j=0;j<w;j++)
                cin>>maze[i][j];
            for(int i=0;i<h;i++){
                for(int j=0;j<w;j++){
                    if(maze[i][j]=='*'||maze[i][j]=='X'){
                        if(!vis[i][j]){
                            memset(cur,0,sizeof cur);
                            dfs(i,j);
                            gao();
                        }
                    }
    
                }
            }
            sort(ve.begin(),ve.end());
            for(int i=0;i<ve.size();i++){
                cout<<ve[i]<<" ";
            }
            cout<<endl<<endl;
    
        }
        return 0;
    }
    

    D - 食物链##

    题目大意:
    白书原题,很多人应该都写过
    题解:
    个人感觉采用一般并查集不是很好理解,下面采用带权并查集。带圈并查集才写了一个题,理解的肯定是不深刻。带权含义是每个节点到根节点的连线上存在一个权值,权值表示一定含义,节点合并时,需要加入权值信息,在路径压缩中,要保持每个节点到根节点权值不变,故需要做一些修改工作。本例中的三个种群分别代码节点到根节点的权值为0,1,2。
    这个题神奇之处是,必须要scanf,cin会TLE。

    #include <iostream>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=5e4+10;
    int n,k;
    int pre[N],val[N];
    void init(){
        for(int i=0;i<=n;i++)pre[i]=i,val[i]=0;
    }
    int find(int x){
        int px=pre[x];
        if(x!=pre[x]){
            pre[x]=find(pre[x]);
            val[x]=(val[x]+val[px])%3;
        }
        return pre[x];
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        int cnt=0;
        init();
        while(k--){
            int d,x,y;
            scanf("%d%d%d",&d,&x,&y);
            int fx=find(x);
            int fy=find(y);
            if(x>n||y>n||(x==y&&d==2))cnt++;
            else if(fx==fy&&(val[x]-val[y]+3)%3!=(d-1))cnt++;
            else if(fx!=fy){
                pre[fx]=fy;
                val[fx]=(val[y]-val[x]+3+(d-1))%3;
            }
        }
        cout<<cnt<<endl;
        return 0;
    }
    

    E - 反正切函数的应用##

    题目大意:
    二元(b,c)一次解方程,求满足条件的最小b+c的值。
    题解:
    有点像高中数学题,但是我没有想到解法。参考网上的,就是变量代换,代换两轮,变成对勾函数的形式,在转折点取到最小值,由于要求整数,所以要枚举。不知道什么只需要枚举左边就好了。

    #include <iostream>
    #include<stdio.h>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int main()
    {
        long long a;
        cin>>a;
        for(int i=a;i>0;i--){
            if((a*a+1)%i==0){
                cout<<(i+(a*a+1)/i+2*a)<<endl;
                break;
            }
        }
        return 0;
    }
    

    F - Euro Efficiency##

    题目大意:
    给定六种硬币面值[1,100),求拼出[1,100]的每个数,最少需要参与的硬币个数为多少。(各种硬币个数不限,可以找钱(也就是做减法))。
    题解:
    完全背包,背包问题必须要很熟悉,经常出现。我这里做法有点不一样,只做了一次完全背包,之后枚举给钱的总钱数,取一个min。
    这个N值要稍大,给的钱数理论最大值为100*100。
    输出用%.lf wa了,也是很神奇,网上说和%.f没有区别,以后还是%.f为妙。

    #include <iostream>
    #include<stdio.h>
    using namespace std;
    int price[6];
    const int N=20000+10;
    int dp[6][N];
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            for(int i=0;i<6;i++){
                cin>>price[i];
            }
            for(int i=0;i<6;i++){
                for(int j=1;j<N;j++){
                    if(i==0)dp[i][j]=j;
                    else{
                        for(int k=0;k<=i;k++){
                        if(j<price[k])break;
                        if(k==0)
                            dp[i][j]=dp[k][j-price[k]]+1;
    
                        else dp[i][j]=min(dp[i][j],dp[k][j-price[k]]+1);
                        }
                    }
                }
            }
            int all=0;
            int maxx=0;
            int cur;
            for(int i=1;i<=100;i++){
                cur=1000;
                for(int j=N-1;j>=i;j--){
                    cur=min(cur,dp[5][j]+dp[5][j-i]);
                }
                maxx=max(cur,maxx);
                all+=cur;
            }
    
            printf("%.2f %d
    ",all/100.0,maxx);
        }
        return 0;
    }
    
    

    G - Tram##

    题目大意:
    简单最短路
    题解:
    建图十分简单,边上的权值0或者1或者INF,再使用任意最短路算法,Floyd最简单,注意Floyd首先枚举中间点。

    #include <iostream>
    #include<stdio.h>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=105;
    const int INF=0x3f3f3f;
    int n,a,b;
    int dis[N][N];
    int main()
    {
        cin>>n>>a>>b;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                dis[i][j]=INF;
              //  if(i==j)dis[i][j]=0;
            }
        }
        for(int i=1;i<=n;i++){
            int k,e;
            cin>>k;
            for(int j=0;j<k;j++){
                cin>>e;
                if(j==0)dis[i][e]=0;
                else dis[i][e]=1;
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++){
                    dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
                }
        if(dis[a][b]>=INF)cout<<-1<<endl;
        else cout<<dis[a][b]<<endl;
        return 0;
    }
    

    H就不做了,逃。。。。。

  • 相关阅读:
    php实现频率限制
    手机号打码
    qxx项目大文件上传
    502错误
    mac 安装phpunit
    文件权限问题
    无题
    php安装redis扩展全
    linux中whereis、which、find、location的区别和用法
    php安装redis扩展
  • 原文地址:https://www.cnblogs.com/gzr2018/p/12372505.html
Copyright © 2011-2022 走看看