2020 字节跳动Byte Camp夏令营 笔试题交流
笔试一共150分钟,从9点到11点半,有单选、不定项选择、填空和编程四道。
回忆中。。。
单选飞速过了,所以题目记不清了。多选第一题是从归并排序、冒泡排序、直接选择排序、堆排序、快速排序、希尔排序选出稳定的排序算法;第二题好像是个操作系统多线程的问题,具体记不得了。
填空第一题是有1、2、、、101共101个数,甲乙两个人轮流取9个数,最后剩两个数,问这两数的绝对值之差S是多少(假设甲乙都足够聪明,甲要使S尽可能大,乙要使S尽可能小) 我也不知道乱猜的55。
填空第二题是a+b+c+d=20的正整数解有多少组。我觉得就是19个空插3个隔板的问题,直接C19、3=969了
接下来是编程题:(前三题比较简单都过了,最后一题暴力O(n2)超时过了50%,如果哪个大佬会请留言,感激不尽)
第一题
给定两维数组,数组中为0或1,1为障碍。给定初始坐标(x,y),给目的地坐标(X,Y),每一步可以上下左右移动,求出初始到结束的最短路径。
直接从初始坐标开始广搜即可。
#include<iostream>
#include<queue>
using namespace std;
struct point{
int x,y,s;
};
int a[105][105],n,m,x1,y1,x2,y2,v[105][105];
queue<point> q;
int main(){
int t; cin>>t;
while(t--){
cin>>m>>n>>y1>>x1>>y2>>x2;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
v[i][j]=0;
}
}
while(!q.empty()) q.pop();
if(x1==x2&&y1==y2){
cout<<"1"<<endl; continue;
}
point p;
p.x=x1; p.y=y1; p.s=1;
q.push(p);
bool flag=false;
while(!q.empty()){
p=q.front();
q.pop();
if(p.x<0||p.x>=n||p.y<0||p.y>=m) continue;
if(v[p.x][p.y]||a[p.x][p.y]) continue;
//cout<<p.x<<" "<<p.y<<endl;
if(p.x==x2&&p.y==y2){
flag=true;
cout<<p.s<<endl;
break;
}
v[p.x][p.y]=1;
point p1; p1.x=p.x+1; p1.y=p.y; p1.s=p.s+1; q.push(p1);
point p2; p2.x=p.x-1; p2.y=p.y; p2.s=p.s+1; q.push(p2);
point p3; p3.x=p.x; p3.y=p.y+1; p3.s=p.s+1; q.push(p3);
point p4; p4.x=p.x; p4.y=p.y-1; p4.s=p.s+1; q.push(p4);
}
if(!flag) cout<<-1<<endl;
}
} 第二题
给定n,两个人每次从中减去1到m任意数,有多组数据,问第一个人能赢的次数。
这个题以前看过的话应该很容易想到,就是看n%(m+1)是否等于0,如果等于0第二个人必赢,否则第一个人必赢。
#include<iostream>
using namespace std;
int main(){
long long t,m,n,ans=0;
cin>>t;
while(t--){
cin>>n>>m;
if(n%(m+1)!=0) ans++;
}
cout<<ans;
} 第三题
第三题就是将json字符串中的注释去掉,注释有//和/* */两种。
这个题主要就是分情况讨论了,用scan.nextLine()依次读取每一行,然后分情况//和/*以及是否在多行注释之间和*/这几种情况讨论,对应输出即可。最后记得每一行最后要System.out.println("");否则直接报PE。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s;
boolean flag=false;
while(scan.hasNext()) {
s=scan.nextLine();
if(flag) {
int index2=s.indexOf("*/");
if(index2==-1) continue;
flag=false;
System.out.print(s.substring(index2+2));
}
int index2=s.indexOf("/*");
if(index2!=-1) {
System.out.print(s.substring(0,index2));
flag=true;
int index3=s.indexOf("*/");
if(index3!=-1) {
flag=false;
System.out.print(s.substring(index3+2));
}
}
else if(!flag) {
int index=s.indexOf("//");
if(index!=-1) {
System.out.print(s.substring(0,index));
}else {
System.out.print(s);
}
}
System.out.println("");
}
}
} 第四题
给定一个n节点的树,gcd(x,y)表示树的x节点到y节点的一条路径上所有节点的最大公约数,dist(表示路径的长度(节点数)。求gcd(x,y)>1的所有路径中最大的dist(x,y)。就是求一条路径上所有节点的公约数值大于1的最长路径。
我直接从所有结点都作为开始,暴力深搜,过了50%。
#include<iostream>
#include<vector>
using namespace std;
vector<int> e[200005];
int n,a[200005],v[200005],ans=1,k[200005];
int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
void f(int i,int now,int p){
v[i]=1;
if(now>ans) ans=now;
for(int j=0;j<e[i].size();j++){
if(!v[e[i][j]]&&k[e[i][j]]){
int pp=gcd(p,gcd(a[i],a[e[i][j]]));
if(pp>1) f(e[i][j],now+1,pp);
else f(e[i][j],1,a[e[i][j]]);
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
k[i]=0;
}
for(int i=0;i<n-1;i++){
int x,y; cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
for(int i=1;i<=n;i++){
for(int j=0;j<e[i].size();j++){
if(gcd(a[i],a[e[i][j]])>1){
k[i]=1; k[e[i][j]]=1;
break;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) v[j]=0;
if(k[i]&&e[i].size()==1) f(i,1,a[i]);
}
if(ans==1) cout<<0;
else cout<<ans;
} 