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

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

题目链接
密码依然是fighting!

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

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

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

B - 回文子串

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

#include 
#include
#include
#include
#include
#include
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

C - The Die Is Cast

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

#include 
#include
#include
#include
#include
#include
#include
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=0&&yve;
void gao(){
    memset(vis2,0,sizeof vis2);
    for(int i=0;i>w>>h&&w!=0){
        cout<<"Throw "<<++T<>maze[i][j];
        for(int i=0;i

D - 食物链

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

#include 
#include
#include
#include
#include
#include
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<

E - 反正切函数的应用

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

#include 
#include
#include
#include
#include
#include
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)<

F - Euro Efficiency

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

#include 
#include
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=i;j--){
                cur=min(cur,dp[5][j]+dp[5][j-i]);
            }
            maxx=max(cur,maxx);
            all+=cur;
        }

        printf("%.2f %d\n",all/100.0,maxx);
    }
    return 0;
}

G - Tram

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

#include 
#include
#include
#include
#include
#include
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>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<

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

你可能感兴趣的:(2018北大计算机学科夏令营机试题目)