网易2021批笔试题解

总结:全是模拟…以及读入处理体验好差hhh

一套卷子(4/4AK)

T3

题目大意:给出一棵树,从0节点开始走m步,求可访问的最多节点数(一个节点访问多次仅算一次)
n , m < = 1000 n,m<=1000 n,m<=1000

真有你的网易…省选原题都拿来出啊…(不过我做过hhh

直接放原题链接了: C Q O I 2017 CQOI2017 CQOI2017 小Q的棋盘

简要题解:
策略是:先考虑直接直接按最长链走,如果走完最长链有多的步数,可以在一开始先走支链,贡献按2步/一个节点算。

故有以下代码:

		for(int i=0;i<=n;i++) mx=Math.max(mx,dep[i]);
		if(m<=mx-1) System.out.println(m+1);
		else System.out.println(Math.min(n,mx+(m-mx+1)/2));

然后dfs算一波就行了。

import java.io.*;
import java.util.*;

public class zbr01
{
    	
	public static int []x=new int [100005];
	static List []g=new List[100005];
	public static int []dep=new int [100005];
	public static int []used=new int [100005];
	public static int n,m;
	
	public static void dfs(int u)
	{
    
		used[u]=1;
		for(int i=0;i<g[u].size();i++)
		{
    
			int v=(int)g[u].get(i); if(used[v]==1) continue;
			dep[v]=dep[u]+1; dfs(v);
		}
	}
	
	public static void main(String[] args)
	{
    
		Scanner S=new Scanner(System.in);
		int n=S.nextInt(),m=S.nextInt(); n--;
		for(int i=0;i<=n;i++) g[i]=new ArrayList <Integer>();
		for(int i=1;i<=n;i++)
		{
    
			int u=S.nextInt(),v=i;
			g[u].add(v); g[v].add(u);
		}
		dep[0]=1; dfs(0); int mx=0;
		for(int i=0;i<=n;i++) mx=Math.max(mx,dep[i]);
		if(m<=mx-1) System.out.println(m+1);
		else System.out.println(Math.min(n,mx+(m-mx+1)/2));
	}
}

T2

题目大意:给出字符串s,求一个最长的连续子串使得其中的 a , b , c , x , y , z a,b,c,x,y,z a,b,c,x,y,z出现次数均为偶数。(复杂度要求 O ( n ) O(n) O(n))

它又又又又来了!hash又是你!!!
将abcdef的出现次数%2,进行hash处理,就能用一个数字表示一个状态了。
(日常学好hash笔试必过)

import java.io.*;
import java.util.*;

public class zbr01
{
    	
	public static int []x=new int [100005];
	
	public static void main(String[] args)
	{
    
		Scanner S=new Scanner(System.in);
		String s=S.nextLine(); int l=s.length();
		int a=0,b=0,c=0,d=0,e=0,f=0,ans=0;
		for(int i=0;i<=64;i++) x[i]=-1; x[0]=0;
		for(int i=0;i<l;i++)
		{
    
			char p=s.charAt(i);
			if(p=='a') a++; else if(p=='b') b++;
			else if(p=='c') c++; else if(p=='x') d++;
			else if(p=='y') e++; else if(p=='z') f++;
			a%=2; b%=2; c%=2; d%=2; e%=2; f%=2;
			int nw=32*a+16*b+8*c+4*d+2*e+f;
			int tmp=x[nw];
			if(tmp==-1) x[nw]=i;
			else if(nw==0) ans=Math.max(ans,i-tmp+1);
			else ans=Math.max(ans,i-tmp);
		}
		System.out.println(ans);
	}
}

T4

题目大意:裸二分图匹配…略略略(连题面都懒得改了吗hhh,直接男女配对了hhh)

下面是网络流大板子+恶心的读入处理emm…

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

inline int read()
{
    
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {
    if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {
    x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

struct node{
    int from,to,cap,flow;};
vector <node> edges;
vector <int> mp[maxn];
int n,m,s,t,d[maxn],cur[maxn];
bool vis[maxn];
queue <int> que;

inline void add_edge(int u,int v,int w)
{
    
	edges.push_back((node){
    u,v,w,0});
	edges.push_back((node){
    v,u,0,0});
	int pp=edges.size();
	mp[u].push_back(pp-2);
	mp[v].push_back(pp-1);
}

inline bool bfs()
{
    
	for(int i=0;i<=t;i++) d[i]=inf,vis[i]=0; d[s]=0; vis[s]=1; que.push(s);
	while(!que.empty())
	{
    
		int u=que.front(); que.pop();
		for(int i=0;i<mp[u].size();i++)
		{
    
			node v=edges[mp[u][i]];
			if(v.cap-v.flow>0&&!vis[v.to])
			{
    
				d[v.to]=d[u]+1;
				vis[v.to]=1; que.push(v.to);
			}
		}
	}
	if(vis[t]) return true;
	return false;
}

inline int dfs(int u,int w)
{
    
	int flow=0,r=0;
	if(u==t||w==0) return w;
	for(int i=0;i<mp[u].size();i++)
	{
    
		node &v=edges[mp[u][i]];
		if(d[v.to]==d[u]+1&&(r=dfs(v.to,min(v.cap-v.flow,w)))>0)
		{
    
			flow+=r;
			edges[mp[u][i]].flow+=r;
			edges[mp[u][i]^1].flow-=r;
			w-=r;
			if(w==0) break;
		}
	}
	return flow;
}

inline int max_flow()
{
    
	int ff=0;
	while(bfs())
	{
    
		memset(cur,0,sizeof(cur));
		ff+=dfs(s,inf);
	}
	return ff;
}

int a[maxn],b[maxn],ca,cb;
map <int,int> pa,pb;

int main()
{
    
	freopen("t1.in","r",stdin);
	string S=""; getline(cin,S);
	int l=S.length(),nw=0;
	for(int i=0;i<l;i++)
	{
    
		if(S[i]==' ')
		{
    
			a[++ca]=nw;
			pa[nw]=ca;
			nw=0;
		}
		else nw=nw*10+S[i]-'0';
	}
	a[++ca]=nw; pa[nw]=ca;
	
	nw=0; getline(cin,S);
	for(int i=0;i<l;i++)
	{
    
		if(S[i]==' ')
		{
    
			b[++cb]=nw;
			pb[nw]=cb;
			nw=0;
		}
		else nw=nw*10+S[i]-'0';
	}
	b[++cb]=nw; pb[nw]=cb; nw=0;
	S=ca+cb+1; t=ca+cb+2;
	
	rep(i,1,ca) add_edge(s,i,1);
	rep(i,1,cb) add_edge(ca+i,t,1);
	
	int Q=read();
	while(Q--)
	{
    
		int u=read(),v=read();
		add_edge(pa[u],ca+pb[v],1);
	}
	printf("%d\n",max_flow());
	return 0;
}

T1

题目大意:给出一颗二叉树,问两个儿子都是叶节点的节点数量。

毫无水平的大模拟…略略略…扔到最后hhh

import java.io.*;
import java.util.*;

public class zbr01
{
    	
	public static int []x=new int [100005];
	static List []g=new List[100005];
	public static int []dep=new int [100005];
	public static int []cnt=new int [100005];
	public static int n,m;
	
	public static void dfs(int u,int fa)
	{
    
		if(g[u].size()==1&&u!=1)
		{
    
			for(int i=0;i<g[u].size();i++)
			{
    
				int v=(int)g[u].get(i);
				cnt[v]++;
			}
		}
		
		for(int i=0;i<g[u].size();i++)
		{
    
			int v=(int)g[u].get(i); if(v==fa) continue;
			dep[v]=dep[u]+1; dfs(v,u);
		}
	}
	
	public static void main(String[] args)
	{
    
		Scanner S=new Scanner(System.in);
		int n=S.nextInt(),m=S.nextInt();
		for(int i=0;i<=n;i++) g[i]=new ArrayList <Integer>();
		for(int i=1;i<=m;i++)
		{
    
			int u=S.nextInt();
			String tmp=S.next(); int v=S.nextInt();
			g[u].add(v); g[v].add(u);
		}
		dep[0]=1; dfs(1,0); int ans=0;
		for(int i=1;i<=n;i++) if(cnt[i]==2) ans++;
		System.out.println(ans);
	}
}

另一套C++题的T4:

题目大意:求两个字符串的编辑距离,有的字符串可以无视。

读入非常恶心…然后编辑距离就是大家都会的非常经典的dp了…详见代码

巨长码农题

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

inline int read()
{
    
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {
    if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {
    x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

map <string,int> p;
string a[maxn],b[maxn];
int dp[1005][1005],ca,cb;

int main()
{
    
	string s; getline(cin,s); int l=s.length();
	string tmp="";
	for(int i=0;i<l;i++)
	{
    
		if(s[i]==' ')
		{
    
			p[tmp]=1;
			tmp="";
		}
		else tmp+=s[i];
	}
	p[tmp]=1; tmp="";
	
	getline(cin,s); l=s.length();
	for(int i=0;i<l;i++)
	{
    
		if(s[i]==' ')
		{
    
			a[++ca]=tmp;
			tmp="";
		}
		else tmp+=s[i];
	}
	a[++ca]=tmp; tmp="";
	
	getline(cin,s); l=s.length();
	for(int i=0;i<l;i++)
	{
    
		if(s[i]==' ')
		{
    
			b[++cb]=tmp;
			tmp="";
		}
		else tmp+=s[i];
	}
	b[++cb]=tmp; tmp="";
	
	rep(i,0,ca) rep(j,0,cb) dp[i][j]=inf; dp[0][0]=0;
	rep(i,1,ca) dp[i][0]=dp[i-1][0]+(p[a[i]]==0);
	rep(i,1,cb) dp[0][i]=dp[0][i-1]+(p[b[i]]==0);
	
	rep(i,1,ca) rep(j,1,cb)
	{
    
		if(p[a[i]]) dp[i][j]=min(dp[i][j],dp[i-1][j]);
		else dp[i][j]=min(dp[i][j],dp[i-1][j]+1);
		
		if(p[b[j]]) dp[i][j]=min(dp[i][j],dp[i][j-1]);
		else dp[i][j]=min(dp[i][j],dp[i][j-1]+1);
		
		if(p[a[i]]&&p[b[j]]) dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
		else dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);
		
		if(a[i]==b[j]) dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
	}
	cout<<dp[ca][cb]<<endl;
	return 0;
}

END:网易读入太恶心了…码量也好大emm…以及这hash是不是已经连着出10多场了hhh…公司之间大家这么有默契???

猜你喜欢

转载自blog.csdn.net/qq_38649940/article/details/108551501
今日推荐