【TODO】2023年秋招笔试未竞

2023年秋招笔试没做完的题

  • 腾讯20230326笔试三道
  • 米哈游20230813笔试第三题
  • 网易雷火0820第2、3、4题
    • 第三题
  • 深信服0912B卷3、4题
    • 第三题(背包装满最小数量)
    • 第四题
  • 腾讯0915重考最后一道
  • 字节0917秋招第五场第一题AC自动机

腾讯20230326笔试三道

米哈游20230813笔试第三题

是计算抽中什么当期五星的期望。
现在的程序结果是99.6087。结果不对,有时间再调。

【TODO】2023年秋招笔试未竞_第1张图片

#include 
#include 
typedef long long LL;
using namespace std;

int n = 90;
double p;
// double min_p = 1e-7;
double min_p = 0.0000000000000001;
vector<vector<double>> dp;

// x 0 保底、1 不保底
// y 0 必、1-89 不必
// acc 累计概率
// 返回抽到当期期望数
double dfs(int x, int y, double acc){
    if(dp[x][y] != -1) return dp[x][y] + 1;
    if(acc <= min_p) {
        // TODO
        cout << x << " " << y << " " << acc << " " << dp[x][y] << "==================" << endl;
        return 1e18;
    }

    double g = 1;

    if(x == 1 && y == 0){
        dp[x][y] = 0.5 + 0.5 * dfs(0, 1, acc * 0.5);
    } else if(x == 0){
        dp[x][y] = p + (g-p) * dfs(0, (y+1) % n, acc * (g-p));
    } else{
        dp[x][y] = p/2 + (p/2) * dfs(0, (y+1) % n, acc * (p/2)) + (g-p) * dfs(1, (y+1) % n, acc * (g-p));
    }
    cout << x << " " << y << " " << acc << " " << dp[x][y] << endl;
    // xxx: 注意!!!要加1
    return dp[x][y] + 1;
}

int main() {
    // int a, b;
    // while (cin >> a >> b) { // 注意 while 处理多个 case
    //     cout << a + b << endl;
    // }
    freopen("D:\\auxiliaryPlane\\project\\scuCode\\input.txt","r",stdin);
	freopen("D:\\auxiliaryPlane\\project\\scuCode\\output.txt","w",stdout);

    // cin >> p;
    p = 0.006;
    // 输出 104.5497057
    // 要求误差在1e-6内

    dp = vector<vector<double>>(2, vector<double>(n, -1));
    // 是否保底,连续没五次数 下次期望
    // 估计一个当前概率阈值
    dp[0][0] = 0;

    cout << dfs(1, 1, 1);
    // cout << 1;
    // cout << min_p;
    // printf("%.3f", min_p);
}
// 64 位输出请用 printf("%lld")

网易雷火0820第2、3、4题

第三题

没调出来

#include 
#include 
using namespace std;

int n, m, a, b;
vector<bool> vis;
vector<vector<int>> team;
vector<vector<int>> stat;
vector<vector<int>> dp;

void maintain(vector<int> &arr){
    int p = 0, n = arr.size();
    for(int i=0;i<n;i++){
        if(vis[arr[i]]) continue;
        arr[p] = arr[i];
        p++;
    }
    int t = n - p;
    while(t--){
        arr.pop_back();
    }
}

void noABFind(){
    maintain(stat[0]);
    maintain(stat[1]);
    maintain(stat[2]);
    maintain(stat[3]);

    // 根据vis和stat[0]维护dp

    int emp = m-2;
    dp = vector<vector<int>>(m-1, vector<int>());
    for(auto &x: stat[0]){
        if(vis[x]) continue;
        for(int i=m-2;i>0;i--){
            if(dp[i].size()) continue;
            int p = i-team[x][0];
            if(p >= 0){
                if(p == 0 || dp[p].size()){
                    // dp[i] = dp[p];
                    for(auto t: dp[p]) dp[i].push_back(t);
                    dp[i].push_back(x);
                    emp--;
                }
            } else break;
        }
        if(emp == 0) break;
    }
}

void output(vector<int> &x){
    sort(x.begin(), x.end());
    for(auto &y : x) {
        vis[y] = true;
        cout << y + 1 << " ";
    }
    cout << endl;
    
}

int main() {
    // int a, b;
    // while (cin >> a >> b) { // 注意 while 处理多个 case
    //     cout << a + b << endl;
    // }
    
    cin >> n >> m >> a >> b;
    // 只要ab职业和总数不超就加,否则就向后找
    vis = vector<bool>(n, false);    // 用过 或 报名失败
    team = vector<vector<int>>(n, vector<int>());     // 几个a,几个b,几个其他
    stat = vector<vector<int>>(4, vector<int>());

    for(int i=0;i<n;i++){
        int t; cin >> t;
        vector<int> arr = {0, 0, 0, 0};
        for(int j=0;j<t;j++){
            int jt; cin >> jt;
            arr[0]++;
            if(jt == a) arr[1]++;
            else if(jt == b) arr[2]++;
            else arr[3]++;
        }
        team[i] = arr;
        if(arr[1] > 1 || arr[2] > 1) vis[i] = true;

        if(arr[1] == 0 && arr[2] == 0) stat[0].push_back(i);
        else if(arr[1] == 1 && arr[2] == 0) stat[1].push_back(i);
        else if(arr[1] == 0 && arr[2] == 1) stat[2].push_back(i);
        else stat[3].push_back(i);
    }
    
    for(int i=0;i<n;i++){
        if(vis[i]) continue;
        if(team[i][1] == 0 && team[i][2] == 0) continue;
        // 以当前有ab的为首查找
        vector<int> cnt = {team[i][0], team[i][1], team[i][2], team[i][3]};
        vector<int> subans = {i};

        noABFind();
        if(cnt[1] == 1 && cnt[2] == 0){
            // 先找有一个b的
            for(auto &j : stat[2]){
                if(vis[j]) continue;
                int t = team[j][0] + cnt[0];
                if(t > m) continue;
                else if(t == m){
                    subans.push_back(j);
                    output(subans);
                    break;
                } else if(dp[m - t].size() != 0){
                    subans.push_back(j);
                    subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
                    output(subans);
                    break;
                }
            }
        } else if(cnt[1] == 0 && cnt[2] == 1){
            for(auto &j : stat[1]){
                if(vis[j]) continue;
                int t = team[j][0] + cnt[0];
                if(t > m) continue;
                else if(t == m){
                    subans.push_back(j);
                    output(subans);
                    break;
                } else if(dp[m - t].size() != 0){
                    subans.push_back(j);
                    subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
                    output(subans);
                    break;
                }
            }
        } else{
            int t = cnt[0];
            if(t > m) continue;
            else if(t == m){
                output(subans);
            } else if(dp[m - t].size() != 0){
                subans.insert(subans.end(), dp[m-t].begin(), dp[m-t].end());
                output(subans);
            }
        }
        vis[i] = true;
    }


}

// 只过了3.33%

// 8 6 1 2
// 4 1 2 3 3
// 1 1
// 1 1
// 1 3
// 5 3 3 3 4 2
// 4 4 5 6 2
// 1 1
// 1 1



// 64 位输出请用 printf("%lld")

深信服0912B卷3、4题

第三题(背包装满最小数量)

有一些长度的木头数组woods[],用这些木头拼接length,每根可取无限个,最少需要多少根木头,拼接不出返回-1。其中1<=len(woods)<=1001<=woods[i]<=10001<=length<=10000。样例(对你没看多,字符串格式的数组,自己解析,和4399一样):

输入:
[1, 2, 3, 5]
9
输出:
3

第四题

现有任务数组t1, t2, t3...tn,每个数表示执行时间,长度为n,现从中挑选k个任务,并保持这k个任务的顺序,将这k个任务分隔为两部分,前一部分给A同学执行,后一部分给B同学执行,每个同学执行时间为任务时间之和,两位同学总时间为两人中的最大时间。问总时间最小是多少,询问T组数据。其中1<=k<=n<=3000001<=ti<=10^9T组数据n的总和<=3 * 10^5,样例:

输入:
2
10 6
10 8 18 13 3 8 6 4 14 12
10 5
9 9 2 11 14 33 4 9 14 12
输出:
21
18

腾讯0915重考最后一道

有n个(105 )点的坐标(1~109),有两种点,红色0和蓝色1,每次可以进行两种操作:

  1. 把红色点坐标+1 / -1;
  2. 把蓝色点变为红色

最多进行第二种操作k次,问最少需要进行第一种操作多少次使得任意两个红色点之间没有蓝色点。

输入n、k、n个点坐标、n个点颜色

#include 
typedef long long LL;
using namespace std;

LL maxx = 1e17 + 1;
int n, k;
vector<LL> x;
vector<bool> c;

vector<int> xr;
vector<int> xb;
// vector vis;
set<int> sset;


LL ans = maxx;

void cal(){
    // 写暴力都很复杂啊
    vector<int> tr = xr;
    for(auto &i : sset){
        tr.push_back(i);
    }
    sort(tr.begin(), tr.end());
    
    vector<int> tb;
    int last_b = -1;
    int pb = 0, pr = 0;
    // 还得过滤掉 三个蓝色点之间都没有红色点的那个中间蓝色点
    while(pr < tr.size() && pb < xb.size()){
        if(sset.count(xb[i])) {
            pb++;
            continue;
        }
        ...
    }
    
    last_b = -1;
    for(int i=1;i<xb.size();i++){
        pb = xb[i];
        LL subans = 0;
        if(sset.count(xb[i])) continue;
        if(last_b == -1){
            last_b = i;
            for(auto &j : tr){
                if(j < pb) continue;
                subans += x[j] - (x[pb] - 1);
            }
        } else{
            
            for(auto &j : tr){
                if(j < last_b) {
                    subans += x[last_b] + 1 - x[j];
                } else if(j > pb){
                    subans += x[j] - (x[pb] - 1);
                }
                
            }
            last_b = i;
        }
        ans = min(ans, subans);
    }
    // 最右边
    ...
    ans = min(ans, subans);
    
}

void dfs(int p, int cnt){
    if(cnt == k){
        cal();
        return ;
    }
    int m = xb.size();
    if(m - p <= k - cnt){
        for(int i=p;i<m;i++){
//             vis[i] = true;
            sset.insert(i);
        }
        cal();
        for(int i=p;i<m;i++){
//             vis[i] = false;
            sset.erase(i);
        }
        return ;
    }
    dfs(p+1, cnt);
//     vis[p] = true;
    sset.insert(p);
    dfs(p+1, cnt+1);
//     vis[p] = false;
    sset.erase(p);
}

int main(){
    // 所有红点要连成一整片
    cin >> n >> k;
    x = vector<LL>(n);
    c = vector<bool>(n);
    for(int i=0;i<n;i++) cin >> x[i];
    int sum = 0, l = -1, r = -1;
    int cnt_blue = 0;
    vector<int> xt;
    for(int i=0;i<n;i++){
        int t; cin >> t;
        if(t == 0) {
            c[i] = true;
            r = x[i];
            if(l != -1){
                xb = xb.insert(xb.end(), xt.begin(), xt.end());
                sum += cnt_blue;
                cnt_blue = 0;
            }
            if(l == -1) l = x[i];
            xr.push_back(i);
        } else {
            if(l != -1){
                xt.push_back(i);
                cnt_blue++;
            }
            c[i] = false;
        }
    }
//     vis = vector(xb.size(), false);
    if(sum <= k) {
        cout << 0;
        return 0;
    }
    
    // cout << 0; // 先拿点分
    
    
    // 前i个蓝色的做了k次操作,这个太复杂了,记录状态,还要考虑新变成红色的。
//     vector> dp(sum + 1, vector(k + 1, maxx));
//     vector> last(sum + 1, vector(k + 1, -1));
//     for(int i=1;i<=sum;i++){
//         for(int j=0;j<=min(i+1, k);j++){
            
//         }
//     }
    
    // 写暴力吧
    dfs(0, 0);
    cout << ans;
    return 0;
}

字节0917秋招第五场第一题AC自动机

#include 
#include 
using namespace std;

struct TireNode{
    
    int ind;
    TireNode* last;
    vector next = vector(26);
    TireNode(int ind){
        ind = ind;
    };
    TireNode(int ind, TireNode* last) {
        ind = ind;
        last = last;
    };
};


vector arr;

TireNode* root;

// void kmp(string par){
//     int m = par.size();
//     arr = vector(m + 1);
//     if(m == 1) return ;
//     // if(par[0] == par[1]) arr[1] = 1;
//     for(int i=1;i 0 && par[j] != par[i]) j = arr[j];
//         if(par[j] == par[i]) arr[i+1] = j + 1;
//         else arr[i+1] = 0;
//     }
// }

void kmp(string par, int index){
    int m = par.size();
    vector tt;
    if(root->next[par[0] - 'a'] == nullptr){
        TireNode* head = new TireNode(-1, root);
        root->next[par[0] - 'a'] = head;
        if(m == 1) {
            head->ind = index;
            return ;
        }
    } else{
        if(m == 1){
            root->next[par[0] - 'a']->ind = index;
            return ;
        }
    }
    tt.push_back(root->next[par[0] - 'a']);
    
    for(int i=1;i 0 && par[j] != par[i]) j = arr[j];
        // if(par[j] == par[i]) arr[i+1] = j + 1;
        // else arr[i+1] = 0;

        TireNode* j = tt[i];
        while(j != root && )
    }
}

int main() {
    int n, q; cin >> n >> q;
    string str; cin >> str;
    root = new TireNode(0);
    while(q--){
        string t; cin >> t;
        // int m = t.size();
        
        // int cnt = 0;
        // 暴力
        // for(int i=0;i<=n-m;i++){
        //     bool flag = true;
        //     for(int j=0;j 0 && t[pt] != str[i]) pt = arr[pt];
        //     if(t[pt] == str[i]) pt++;
        //     else pt = 0;

        //     if(pt == m){
        //         cnt++;
        //         pt = arr[m];
        //     }
        // }

        
        

        // AC 自动机?


        cout << cnt << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

你可能感兴趣的:(面经,算法,数据结构,概率论)