题型
- 编程 3道 150分钟
这次时间是真的充分
编程1:大刀砍补给
有一张m*m大小的地图,小明站在地图的一个点上,他有一把l长的大刀,地图上有分布的补给,每次砍到补给都可以使大刀延长x米
- 输入:两个数m,l,接下来m行,每行m个数,代表地图,0为空地,其他值代表补给x,接下来一行两个数,代表小明的起始位置,小明不会移动;
- 输出:大刀的最长值
- 思路:保存所有有补给的点,计算这些点到小明的距离,然后排序,每次判断小明是否可以砍到最近的补给,可以就延长大刀,否则跳出,然后输出。
编程2:字符串操作
给定n个数,大小为1 ~ n,开始时每个数输一个集合,定义三种操作:
1:将x和y所在的两个集合合并,若x和y在同一集合,不作操作;
2:将x从所在集合提出,单成一个集合,若x所在集合只有一个元素,不作操作;
3:输出x所在集合的大小。
- 输入:n,m,记下来m行代表m个操作,每行第一个数字代表操作序号,后面有一个数字或者两个代表需要操作的数字;
- 输出:对于每次3号操作,输出一个数;
- 思路:用一个map存储数字所在集合的编号,用一个
vector<set<int>>
存储实际的集合情况,按照操作要求写逻辑即可。
编程3: 错排最小权值
定义错排为:若B为A的一个错排,则B中每个元素的位置都不在原来的A中的位置;
定义错排权值:val += vi * |xi.pos(a) - xi.pos(b)| x~[0,n-1]
,vi代表第i个元素的权重,xi.pos(a)代表x在A中的位置,xi.pos(b)代表B在A中的位置。
- 输入:n,接下来一行n个数,代表排列A,接下来一行n个数,代表第i个元素的权值;
- 输出:一个数,最小错排权值
- 思路:想了一下,和实际排列元素的值无关,所以直接把排列A定义为
0 1 2 3 4...
,然后调用next_permutation()
函数求全排列,对每一个排列验证其是否为错排,是的话就计算权值然后更新全局最小值,但是并没有AC。
后面剩五分钟的时候,感觉既然和实际元素的值无关,那么我们只关注权值的话,有这么一个规律,如果n为偶数的话,两两相邻元素交换位置应该就是最小权值,pos全部为1,等于直接把所有元素的权值加起来;n为奇数的话,先找到权值最小的元素,然后做一个什么处理(还没想到)也可以直接求出最小权值。。。奈何没时间了。。。
下面一段本地IDE保留的代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<climits>
//#include<set>
using namespace std;
int minval;
int findpos(vector<int> &curr, int x);
int helper(map<int, int> &v, vector<int> &curr);
bool judge(vector<int> &curr);
int main(){
int t;
cin >> t;
while (t--)
{
minval = INT_MAX;
int n;
int temp;
cin >> n;
vector<int> nums(n);
map<int, int> v;
for (int i = 0; i<n; i++)
{
//考虑元素序号即可
cin >> temp;
nums[i] = i;
}
for (int i = 0; i<n; i++)
{
cin >> v[i];
}
vector<int> curr(nums.begin(), nums.end());
while (next_permutation(curr.begin(), curr.end()))
{
if (judge(curr))
minval = min(minval, helper(v, curr));
}
cout << minval << endl;
}
return 0;
}
bool judge(vector<int> &curr)
{
for (int i = 0; i < curr.size(); i++)
{
if (curr[i] == i)
return false;
}
return true;
}
int helper(map<int, int> &v, vector<int> &curr)
{
int val = 0;
for (int i = 0; i<curr.size(); i++)
{
val += v[i] * abs(i - findpos(curr, i));
}
return val;
}
int findpos(vector<int> &curr, int x)
{
for (int i = 0; i<curr.size(); i++)
if (curr[i] == x)
return i;
return -1;
}