題型
- 編程 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;
}