记录网易雷火笔试


1、交换完全二叉树某子树
        第一眼看上去需要建立二叉树,但是因为是完全二叉树,可以直接用数组代替,对于每个节点n,其子树为2n和2n+1,因此直接根据这个规律操作数组即可。
        因为对于节点n,其子树也需要交换,因此这里采用递归,对节点n的子树及其子树节点也进行交换。
        对于节点n,首先判断其左右子树是否存在,如果不存在,直接返回;如果存在,则对左右子树进行递归,最后左右子树全部交换完后,再对当前节点的左右子树进行交换。

#include<iostream>
#include<vector>

using namespace std;

void dfs(vector<int> &arr, int left, int right)
{
	if (left > arr.size() - 1 || right > arr.size() - 1)
		return;
	else
	{
		dfs(arr, 2 * left+1, 2 * right+1);
		dfs(arr, 2 * (left + 1), 2 * (right + 1));
		swap(arr[left], arr[right]);
		return;
	}
}

int main()
{
	vector<int> arr = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
	int n = 3;
	dfs(arr, 2 * n-1, 2 * n);

	for (int i = 0; i < arr.size(); i++)
		cout << arr[i] << " ";
	cout << endl;

	system("pause");
	return 0;
}





2、有N种商品,每种商品有N_i个,现在需要将K个不同的商品放入福袋中,问最多可以做多少个福袋
        我的思路是,尽可能先拿个数多的那种商品。
        首先将个数最多的K个商品,每种中拿出1个,然后对剩余的个数进行排序,再从个数最多的K个中每种拿出一个...每次拿之前先判断剩余商品种类是否大于K个。
int main()
{
    int N, K;
    cin >> N >> K;
    vectorarr(N, 0);
    for(int i = 0; i< N; i++)
        cin >> arr[i];
    int flag = 0;
    int res = 0;
    while(1)
    {
        flag = 0;
        for(int i = 0; i< N; i++)
            if(arr[i] > 0)
                flag++;
        if(flag < K)
            break;

        sort(arr.begin(), arr.end());

        for(int i = arr.size()-1; i >= arr.size()-K; i--)
            arr[i]--;

        res++;
    }

    cout << res << endl;

    return 0 ;
}




3、老王打字:①输入一个字母,步数加1;选定全部已输入字符,步数加2;复制全部选定字符,步数加2;粘贴全部复制字符,步数加2;按ESC取消选择,步数加1;

问:输入N个字最少需要多少步。
动态规划:

    假设F(n)表示输入n个字需要的步数。
    F(0) = 0;
    F(1) = 1;
    F(2) :分情况讨论:①在输入了1个字的基础上,再输入1个字,即F(2) = F(2-1) + 1;②第二、三种情况,这里不明显,后面讨论
    F(3) :分情况讨论:①在输入1个的基础上输入2个,在输入2个的基础上输入1个,即F(3) = min( F(3-2) + 2,  F(3 - 1) + 1),两种情况中取最小值;②第二、三种情况,这里还是不明显,下一步讨论
    ........
    F(10) :分情况讨论:
    ①即为上面,在输入了i个字符的基础上,再输入10-i个,(i为从1到9);
    ②第二种情况:输入了i个字符后,我复制这i个字符,取消选择,然后在后面进行多次粘贴,这里的i可以从1到10/2;循环取i,求最小值,需要注意的是,当10%i不为0时,需要再加上F(10%i);
    ③第三种情况:输入了i个字符后,我还是复制粘贴这i个字符,但是上面②是复制之后,取消选择,在原来的后面继续粘贴;这里我复制之后,输入一个字符,将原来输入的都覆盖掉,然后再粘贴;


int main()
{
    int N;
    cin >> N;
    vectordp(N+1, 99999);
    dp[0] = 0;
    dp[1] = 1;
    for(int i = 2; i <= N; i++)
    {
        for(int j = 1; j <= i; j++)
            dp[i] = min(dp[i], dp[i-j] + j); //情况①
        for(int j = 1; j <= i/2; j++)
        {
            dp[i] = min(dp[i], dp[j] + i/j*2 + 3 + dp[i%j]); //情况②
            dp[i] = min(dp[i], dp[j] + i/j*2 + 5); //情况③
        }
    }

    cout << dp[N] << endl;

    return 0;
}


全部评论
第二题i在n-k的时候应该能取等,第三题乘2直接少了*
1 回复 分享
发布于 2020-08-03 14:19
第一题可不可以用后序遍历? void postOrder(int root,int flag) { if(root==-1) return; if(root==x) flag=true; postOrder(Node[root].lchild,flag); postOrder(Node[root].rchild,flag); if(flag==true) swap(Node[root].lchild,Node[root].rchild); }
点赞 回复 分享
发布于 2020-08-23 22:51
第三题是这么个意思吗 """ 老王打字: 输入一个字母,步数加1; 选定全部已输入字符,步数加2; 复制全部选定字符,步数加2; 粘贴全部复制字符,步数加2; 按ESC取消选择,步数加1; 问:输入N个字最少需要多少步。 """ # 输入 n = int(input().strip()) dp = [0 for _ in range(n+1)] dp[0] = 0 # 首先确定,最后一次操作要么是输入,要么是粘贴 for i in range(1, n+1): # 1. 最后1步是输入的最小值 dp[i] = dp[i-1]+1 # 2. 最后1步是粘贴的最小值,因为可以多次粘贴,所以需要循环找最后几步都是粘贴的情况, for j in range(2,int(i/2)): # 首先要满足i个字符是j的倍数(一次全选,然后多次粘贴) if i%j != 0: continue # 粘贴j个字符,说明在dp[j]的时候做了全选的操作(+2),取消选择后粘贴是为了避免覆盖掉前面的内容(+1),然后粘贴(i-j)/j次(+((i-j)/j)*2) dp[i] = min(dp[i], int(dp[j]+2+1+((i-j)/j)*2)) # 输出 print(dp[n])
点赞 回复 分享
发布于 2020-08-08 14:43
楼主太强了
点赞 回复 分享
发布于 2020-08-08 10:31
你好,LZ,我想问一下,第三题的第三种情况,能举个例子说明一下吗?我没看明白怎么回事
点赞 回复 分享
发布于 2020-08-04 19:29
我测试一下第一题,博主输出的结果好像只是找到M=3这个节点,然后交换左右子树,所以输出结果为:1 2 3 4 5 7 6 8 9 10 11 14 15 12 13。但是按照翻转的话,输出的结果应该是:1 2 3 4 5 7 6 8 9 10 11 15 14 13 12。我都忘了第一题的题目了要求是什么
点赞 回复 分享
发布于 2020-08-03 17:11
当10%i不为0时,需要再加上F(10%i)这个不太理解,题主能解释一下吗
点赞 回复 分享
发布于 2020-08-03 14:44
博主这些答案都是当时AC的么 还是事后写出来的
点赞 回复 分享
发布于 2020-08-03 14:06
厉害
点赞 回复 分享
发布于 2020-08-03 12:46
第一题感觉是不有问题,能详细点吗
点赞 回复 分享
发布于 2020-08-02 21:23
dp[i] = min(dp[i], dp[j] + i/j2 + 3 + dp[i%j]); //情况② 你好,这里+3我没理解,应该是先全选,复制,esc,应该是5步啊。为什么这里只有3步
点赞 回复 分享
发布于 2020-08-02 20:12

相关推荐

03-10 10:57
已编辑
门头沟学院 推荐算法
夜夜还好:我们学校说为了学生就业,更新了课程,我今天大二,上学期在学jsp,html,这学期上来工程实践,要求用springboot+vue,说什么这些技术要我们提前自己准备,要不你把学费还我吧,我给b站充个会员,人家教的比你多
点赞 评论 收藏
分享
评论
7
17
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务