阿里 2020暑期实习生 笔试回忆

题型

  • 编程 2道 60min

编程1: 修水渠

给若干点的坐标,代表每一个村子,现在要修一条平行于y轴且无限长的水渠,求所有村庄距离这条水渠垂直长度之和的最小值。

  • 输入:n代表村庄的个数,接下来n行,每行2个数,代表村庄的坐标,x>=0,y<=10000
  • 输出:一个数,代表最小距离
  • 思路:想了一下好像和纵坐标没关系,然后拿笔试了试,认定水渠的x值必是和某一村庄的x相同(感觉有点被给出的样例误导),然后就开始了错误的解题过程。。。
    后来想了一下,暴力解的话,可以从最左边的村庄位置开始,不断x+=1遍历到最右边的村庄位置,得到最小距离,优化的话,在第i-1和第i个村庄之间的距离,dis = dis - ( n - i ) + i,即dis = dis + 2i -n,每向右增加一各单位距离,左边的所有村庄距离水渠位置都+1,右边的所有村庄距离水渠位置都-1 。
    找几个用例手工算的话,发现如果村庄的数量是奇数,就选中间的村庄,是偶数,就选第n/2和第n/2+1个村庄之间的任意位置,实际上这两个村庄的位置也是最小位置,这么说来不论怎么选最小位置还是在某个村庄的位置,那么问题来了,为什么没有通过测试用例。。。忘记排序了。。。想哭
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>

using namespace std;

int main(){
	int n;
	cin >> n ;
	vector<int> x(n);
	vector<int> y(n);
	for (int i = 0; i < n; i++)
		cin >> x[i] >> y[i];
	//初始化长度
	int curr = 0, minVal = INT_MAX;
	sort(x.begin(), x.end());
	for (auto a : x)
		curr += (a - x[0]);
	for (int i = 1; i < n; i++)
	{
		curr = curr + i*(x[i] - x[i - 1]) - (n - i)*(x[i] - x[i - 1]);
		minVal = min(minVal, curr);
	}
	cout << minVal;
	system("pause");
	return 0;
}

编程2:涂色

给定一个n*m的矩阵,给定c种颜色的染料,以及每种染料的数量,试问是否有一种方法给矩阵染色,使得每个方块的与他上下左右的颜色均不同。

  • 输入:n,m,c,接下来一行c个数,代表每种染料的数量
  • 输出:YES或NO
  • 思路:当时看到一眼想起一个什么定律,如果有3种还是4种不同颜色的染料对什么东西进行染色,必可以满足相邻位置不同色。
    其实当时也想到了递归,但总觉得递归会超时,就没写。。。当时想的是按照斜线的方式遍历矩阵,从第一个颜色开始按顺序往下涂,遍历完能涂完就输出YES,真是智障实锤了,考完了想了想,这不就是八皇后的翻版吗。。。直接递归就完事了

代码写的比较菜。。。但应该可以AC一部分吧。。。
递归的结束条件和里面的循环可能写的不是很好,会增加一些运行时间

#include<iostream>
#include<vector>

using namespace std;

void recurse(vector<vector<int>> &map, vector<int> col, int x, int y);

bool tag = false;

int main(){
	int n, m, c;
	cin >> n >> m >> c;
	vector<int> col(c);
	for (auto &a: col)
	{
		cin >> a;
	}
	vector<vector<int>> map(n, vector<int>(m, -1));
	recurse(map, col, 0, 0);
	cout << (tag ? "YES" : "NO");
	system("pause");
	return 0;
}

void recurse(vector<vector<int>> &map, vector<int> col, int x, int y)
{
	if (tag) return;
	if (y >= map[0].size())
	{
		y = 0;
		x++;
	}
	if (x >= map.size())
	{
		tag = true;
		return;
	}
	for (int i = 0; i < col.size(); i++)
	{
		if (y - 1<0 || (col[i] > 0 && map[x][y - 1] != i))
		if (x - 1<0 || (col[i] > 0 && map[x - 1][y] != i))
		{
			map[x][y] = i;
			col[i]--;
			recurse(map, col, x, y + 1);
			col[i]++;
			map[x][y] = -1;
		}
	}
}

笔试的时候时间的影响实在是太大了,完全不敢认真的去思考,还有对测试用例的无序性一定要记住,该递归就递归,先作出来再说。

发布了26 篇原创文章 · 获赞 16 · 访问量 5860

猜你喜欢

转载自blog.csdn.net/weixin_44826484/article/details/105428259
今日推荐