华为2021届实习机试题

  • 笔试正确率:20% + 20% + 100%
  • 笔试分数:0.2 * 100 + 0.2 * 200 + 1* 300= 360分,过100分数线
  • 4.8号机试,目前很多题目细节不太记得了,是4月下旬面试前一晚翻之前的草稿纸才回忆起一些题目。再加上牛客网已经有大佬分享了部分题目,总结一下机试题目。

牛客网可以参考以下链接:
https://www.nowcoder.com/discuss/403185?type=post&order=time&pos=&page=1&channel=
https://www.nowcoder.com/discuss/403134?type=all&order=time&pos=&page=1&channel=

1. 快速幂

  • 描述某种情景(不泄露具体细节,其实也是忘了),题目进行总结发现实质就是排列组合之后,求等比数列之和。
  • 但是数太大,需要对1e9+7取余(又或者是1e8+7)。
  • 实际考察点:快速幂、大数幂。
  • 虽然剑指offer刷斐波那契那题有这种思想,但是考场紧张完全没想到这一点。
  • 怕后面来不及,直接从数学角度分析快速的方法了,只AC20%。
int power(int a, int n, int mod)
{
	long long ans = 1;
	while (n > 0)
	{
		if (n & 1 == 1)
			ans = a * ans % mod;
		a = a * a % mod;
		n = n >> 1;
	}
	return ans;
}

2. 应该是一道错题

题目说一个二进制串,可以进行一些字符的替换。
00 ⇒ 10
10 ⇒ 01
可以无限操作,求二进制串可以达到的最大值。

  • 这题搞了20多分钟,一直卡在20%。
  • 下面有牛客网别人晒的思路正确代码。

如果是00,直接替换为10;
如果是11,不做修改;
如果是10,当前一个数也为0,即010的情况,可以替换为101,否则不做修改;
如果是01,同第3条。

作者:沉迷单车
链接:https://www.nowcoder.com/discuss/403185?type=post&order=time&pos=&page=1&channel=
来源:牛客网

typedef long long int ll;
 
int main(){
    int T;
    ll n;
    string s;
    cin>>T;
    for(int i=0;i<T;i++){
        cin>>n>>s;
        for(int j=0;j<n-2;j++){
            if(s[j]=='0'&&s[j+1]=='0'){
                s[j] = '1';
            }else if(s[j]=='0'&&s[j+1]=='1'&&s[j+2]=='0'){
                s[j]='1';
                s[j+1]='0';
                s[j+2]='1';
            }
        }
        if(s[n-2]=='0'&&s[n-1]=='0'){
            s[n-2]='1';
        }
        cout<<s<<endl;
    }
    return 0;
}

但是,这里不是完全正确的。
比如,对于01110,这个结果还是01110。
但是,01110 => 01101 => 01011 => 00111 => 10111,显然大于10111。

这里贴一下我修改的代码(也不一定对,输入输出格式忘记了,其他有错误可以指出)

int main()
{
	int n;
	string s;
	cin >> n >> s;
	int pLeft = 0;
	while (pLeft < n)
	{
		if (s[pLeft] == '1')
			pLeft++;
		else
		{
			int pRight = pLeft+1;
			while (pRight < n)
			{
				if (s[pRight] == '1')
					pRight++;
				else
				{
					s[pLeft] = '1';
					s[pRight] = '1';
					s[pLeft + 1] = '0';
					break;
				}
			}
			pLeft++;
		}
	}
	cout << s << endl;
	return 0;
}

3. 数独
经典题。
我直接用暴力方法强解的,AC100%。

#define SIZE 9
bool processCoreForZeros(int nums[SIZE][SIZE], int begin, int& i, int &j)
{
	for (int ii = begin; ii < SIZE; ii++)
		for (int jj = 0; jj < SIZE; jj++)
		{
			if (0 == nums[ii][jj])
			{
				i = ii;
				j = jj;
				return true;
			}
		}
	return false;
}
bool processCoreForChange(int nums[SIZE][SIZE], int i, int j)
{
	int n = 0;
	while (n <= 8)
	{
		n++;
		bool find = false;
		for (int ii = 0; ii < 9; ii++)
		{
			if (nums[ii][j] == n)
			{
				find = true;
				break;
			}
		}
		if (find)
			continue;

		find = false;
		for (int jj = 0; jj < 9; jj++)
		{
			if (nums[i][jj] == n)
			{
				find = true;
				break;
			}
		}
		if (find)
			continue;

		find = false;
		for (int ii = (i / 3) * 3; ii < (i / 3) * 3 + 3; ii++)
		{
			if (find)
				break;
			for (int jj = (j / 3) * 3; jj < (j / 3) * 3 + 3; jj++)
			{
				if (nums[ii][jj] == n)
				{
					find = true;
					break;
				}
			}
		}

		if (find)
			continue;

		nums[i][j] = n;
		int new_i = 0, new_j = 0;
		if (processCoreForZeros(nums, i, new_i, new_j) == false)
			return true;
		if (processCoreForChange(nums, new_i, new_j) == false)
		{
			nums[i][j] = 0;
			continue;
		}
		else
			return true;

	}
	return false;
}
void processCore(int nums[SIZE][SIZE])
{
	int i = 0;
	int j = 0;
	int begin = 0;
	processCoreForZeros(nums, begin, i, j);
	processCoreForChange(nums, i, j);
}

int main()
{
	int nums[SIZE][SIZE];
	for (int i = 0; i < SIZE; i++)
	{
		getchar();
		for (int j = 0; j < SIZE; j++)
		{
			cin >> nums[i][j];
			getchar();
		}
		getchar();
	}
	processCore(nums);
	for (int i = 0; i < SIZE - 1; i++)
	{
		cout << "{";
		for (int j = 0; j < SIZE - 1; j++)
			cout << nums[i][j] << ',';
		cout << nums[i][SIZE - 1] << '}'<<endl;
	}
	cout << "{";
	for (int j = 0; j < SIZE - 1; j++)
		cout << nums[SIZE - 1][j] << ',';
	cout << nums[SIZE - 1][SIZE - 1] << '}';
	system("pause");
	return 0;
}

你可能感兴趣的:(笔试面试,c++,面试)