腾讯2021校园招聘-技术研究类和数据分析-第一次笔试20200823

过题状况c++

第一题:100%
第二题:100%
第三题:100%
第四题:100%
第五题:100%web

第一题
在这里插入图片描述svg

经典区间dp问题,dp[i][j]表明着从字符串i位置到j位置须要的最小括号匹配数,若是第i个位置和第j个位置的两个括号是匹配的,那么dp[i][j] = dp[i+1][j-1],至关于两边分别往里缩了一个;当i<j时,dp[i][j] = dp[i][k]+dp[k+1][j] ;ui

#include<bits/stdc++.h>
using namespace std;
const int maxn=222;
int dp[maxn][maxn];
int main(){
    string s;cin>>s;
    int len=s.length();
    for(int i=0;i<len;i++)
        dp[i][i]=1;
    for(int l = 1; l < len; l++){
        for(int i = 0; i < len - l; i++){
            int j = i + l;
            dp[i][j]=len;
            if((s[i]=='[' && s[j]==']') || (s[i]=='(' && s[j]==')'))
                dp[i][j] = min(dp[i][j], dp[i+1][j-1]);
            for(int k = i; k < j; k++)
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]);
        }
    }
    printf("%d\n",dp[0][len-1]);
}

第二题:
在这里插入图片描述spa

学太高数的都会,简单的一个积分题3d

#include<bits/stdc++.h>
using namespace std;
double solve(double a, double b, double x){
    return a*x*x*x/3+x*x/2+b*x;
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        double A,B,C,D;
        cin>>A>>B>>C>>D;
        double ans=solve(A,B,D)-solve(A,B,C);
        printf("%lf\n",ans);
    }
}

第三题:
在这里插入图片描述code

很简单答案为C(n,1)*1+C(n,2)*2+C(n,3)*3…,看到这是否是很熟悉了
ans=C(n,0)*0+C(n,1)*1+C(n,2)*2+C(n,3)3…+C(n,n)n 正着写
ans=C(n,n)n+C(n,n-1)(n-1)+… 反着写
两个加起来2ans=n
2^n
ans=n
2^(n-1)便可,用快速幂xml

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long quick_pow(long long a,long long b){
    long long ans=1;
    while(b){
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main(){
    long long n;
    cin>>n;
    cout<<n*quick_pow(2, n-1)%mod<<endl;
}

第四题:
在这里插入图片描述blog

STL大法好,set+map轻松作到排序+计数排序

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+200;
set<int>g[maxn];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].insert(y);
        g[y].insert(x);
    }
    map<set<int>, int>q;
    for(int i=1;i<=n;i++)
        if(g[i].size()!=0)
            q[g[i]]+=1;
    long long ans=0;
    map<set<int>, int>::iterator it;
    for(it=q.begin();it!=q.end();it++){
        int num=it->second;
        if(num>1)
           ans+=1ll*num*(num-1)/2;
    }
    cout<<ans<<endl;
}

第五题
在这里插入图片描述

很简单的想法,最短路便可,注意!!!坑点在于有重边,我还暴力写了个dfs+剪枝,过了55%

最短路

#include<bits/stdc++.h>
using namespace std;
const int INF=1e9;
const int maxn=2222;
int v[maxn];
int dis[maxn], a[maxn][maxn];
int n,m,k;
void Dj()
{
	for (int i = 2; i <= n; i++)
		dis[i] = INF;
	dis[1] = 0;
	memset(v, 0, sizeof(v));
	for (int i = 1; i <= n; i++)
	{
		int u = -1, minn = INF;
		for (int j = 1; j <= n;j++)
			if (v[j] == 0 && dis[j] < minn)
			{
				minn = dis[j]; u = j;
			}
        if(u==-1)
            break;
		v[u] = 1;
		for (int j = 1; j <= n; j++)
			if (v[j] == 0)dis[j] = min(dis[j], dis[u] + a[u][j]);
	}
}
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            a[i][j]=INF;
    while(m--){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        a[x][y]=min(a[x][y],z);
        a[y][x]=min(a[y][x],z);
    }
    while(k--){
        int x,y;
        scanf("%d%d",&x,&y);
        a[x][y]=0;
    }
    Dj();
    if(dis[n]==INF)
        dis[n]=-1;
    cout<<dis[n]<<endl;
}

暴力dfs

#include<bits/stdc++.h>
using namespace std;
const int maxn=2222;
vector<pair<int,int> >G[maxn];
vector<int>K[maxn];
int n,m,k,ans=1e9;
int vis[maxn];
void dfs(int u,int fa,int step){
    if(u==n){
        if(step<ans)
            ans=step;
        return;
    }
    if(step>=ans)
        return;
    for(int i=0;i<K[u].size();i++){
        int v=K[u][i];
        if(v==fa||vis[v])
            continue;
        vis[v]=1;
        dfs(v,u,step);
        vis[v]=0;
    }
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i].first, w=G[u][i].second;
        if(v==fa||vis[v])
            continue;
        vis[v]=1;
        dfs(v,u,step+w);
        vis[v]=0;
    }
}
int main(){
    cin>>n>>m>>k;
    while(m--){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        G[x].push_back(make_pair(y,z));
        G[y].push_back(make_pair(x,z));
    }
    while(k--){
        int x,y;
        scanf("%d%d",&x,&y);
        K[x].push_back(y);
    }
    vis[1]=1;
    dfs(1,0,0);
    if(ans==1e9)
        ans=-1;
    cout<<ans<<endl;
}