题型
- 编程 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;
}
}
}
笔试的时候时间的影响实在是太大了,完全不敢认真的去思考,还有对测试用例的无序性一定要记住,该递归就递归,先作出来再说。