题目描述:
小易将n个棋子摆放在一张无限大的棋盘上,第i个棋子放在第x[i]行y[i]列。同一个格子允许放置多个棋子。每一次操作小易可以把一个棋子拿起并将其移动到原格子的上、下、左、右的任意一个格子中。小易想知道要让棋盘上出现一个格子至少有i(1<=1<=n)个棋子所需要的最少操作数。
输入描述:
输入包括三行,第一行一个整数n(1<=n<=50),表示棋子的个数
第二行为n个棋子的横坐标x[i](1<=x[i]<=10^9)
第三行为n个棋子的纵坐标y[i](1<=y[i]<=10^9)
输出描述:
输出n个整数,第i个表示棋盘上有一个格子至少有i个棋子所需要的操作数,以空格分割。行末无空格
如样例所示:
对于1个棋子:不需要操作
对于2个棋子:将前两个棋子放在(1, 1)中
对于3个棋子:将前三个棋子放在(2, 1)中
对于4个旗子:将所有的棋子放在(3, 1)中
输入样例1:
4
1 2 4 9
1 1 1 1
输出例子1:
0 1 3 10
题目分析:
对于一个格子放n个棋子所需的操作步骤,是求这些棋子到它们中心点的距离之和;对于求一个格子放n-1个棋子,则需要先从n个棋子中剔除掉一个最远的棋子,再对剩下n-1个点,求它们到中心点的距离之和,以此类推。在其中,需要生成一个最小生成树,来快速地搜索最远的棋子。
// Source.cpp
// ------------------------------------------------------------------ -
// Reference:
// Authors : LSS
// Date : 13 / 08 / 2017
// Last modified : 13 / 08 / 2017
// ------------------------------------------------------------------ -
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
using namespace std;
typedef struct Coords
{
int x =-1;
int y =-1;
};
bool DistCompare(pair<int, Coords> s1, pair<int, Coords> s2) { return s1.first < s2.first; }
bool PairIntIntCompareMin(pair<int, int> s1, pair<int, int> s2) { return s1.first < s2.first; }
bool PairIntIntCompareMax(pair<int, int> s1, pair<int, int> s2) { return s1.first > s2.first; }
int MinStep(vector<int> &X, vector<int> &Y, vector<bool> &binsel, int m)
{
int cordx;
int cordy;
int sumx = 0;
int sumy = 0;
int sumn = 0;
for (int i = 0; i < X.size(); i++)
{
if (binsel[i])
{
sumx += X[i];
sumy += Y[i];
sumn += 1;
}
}
if (sumn != m)
return -1;
cordx = round((double)sumx / m);
cordy = round((double)sumy / m);
int minstep = 0;
for (int i = 0; i < X.size(); i++)
{
if (binsel[i])
minstep = minstep + abs(X[i]-cordx)+ abs(Y[i]-cordy);
}
return minstep;
}
int main(int argc, char** argv[])
{
int n;
while (cin >> n)
{
vector<int> X(n, 0);
vector<int> Y(n, 0); // the integral coordinate
for (int i = 0; i<n; i++)
{
cin >> X[i];
}
for (int i = 0; i < n; i++)
{
cin >> Y[i];
}
// Minimum Spanning Tree
vector<vector<int>> G(n, vector<int>(n, INT_MAX));
vector<pair<int, Coords>> distCoords(n*(n-1)/2, make_pair(1, Coords())); //(dist, x, y)
int tempt = 0;
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
G[i][j] = abs(X[i] - X[j]) + abs(Y[i] - Y[j]);
G[j][i] = G[i][j];
Coords temp;
temp.x = i;
temp.y = j;
/*distCoords[tempt++] = make_pair(G[i][j], Coords{i, j});*/
distCoords[tempt++] = make_pair(G[i][j], temp);
}
}
sort(distCoords.begin(), distCoords.end(), DistCompare);
/*for (size_t i = 0; i < distCoords.size(); i++)
{
cout << distCoords[i].first << ' ' << distCoords[i].second.x << ' ' << distCoords[i].second.y << endl;
}
*/
vector<bool> binVecs(n, false);
vector<vector<pair<int, int>>> vecsEdges(n); // pair(int dist, vec i)
for (size_t i = 0; i < distCoords.size(); i++)
{
if (!(binVecs[distCoords[i].second.x] & binVecs[distCoords[i].second.y]))
{
vecsEdges[distCoords[i].second.x].push_back(make_pair(distCoords[i].first, distCoords[i].second.y));
vecsEdges[distCoords[i].second.y].push_back(make_pair(distCoords[i].first, distCoords[i].second.x));
binVecs[distCoords[i].second.x] = true;
binVecs[distCoords[i].second.y] = true;
}
}
/* for (int i = 0; i < n; i++)
{
for (int j = 0; j < vecsEdges[i].size(); j++)
{
cout << vecsEdges[i][j].first << ' ' << vecsEdges[i][j].second << ' ';
}
cout << endl;
}*/
vector<pair<int, int>> vecCounts(n, make_pair(INT_MAX, INT_MAX)); // pair(int count, int vec)
for (size_t i = 0; i < n; i++)
{
vecCounts[i] = make_pair(vecsEdges[i].size(), i);
}
sort(vecCounts.begin(), vecCounts.end(), PairIntIntCompareMin);
if (vecCounts[0].first != 1)
{
cout << "The consruct MST is error" << endl;
return -1;
}
/*for (size_t i = 0; i < vecCounts.size(); i++)
{
cout << vecCounts[i].first << ' ' << vecCounts[i].second << endl;
}*/
vector<pair<int, int>> heapdistVecsCountEq1;//pair(int dist, int vec)count==1
for (size_t i = 0; i < n; i++)
{
if (vecCounts[i].first == 1)
{
int mind = INT_MAX;
for (int j = 0; j < vecsEdges[vecCounts[i].second].size(); j++)
{
mind = min(mind, vecsEdges[vecCounts[i].second][j].first);
}
heapdistVecsCountEq1.push_back(make_pair(mind, vecCounts[i].second));
}
else
break;
}
make_heap(heapdistVecsCountEq1.begin(), heapdistVecsCountEq1.end(), PairIntIntCompareMin);
/*for (size_t i = 0; i < heapdistVecsCountEq1.size(); i++)
{
cout << heapdistVecsCountEq1[i].first << ' ' << heapdistVecsCountEq1[i].second << endl;
}
cout << heapdistVecsCountEq1.front().first << ' ' << heapdistVecsCountEq1.front().second << endl;*/
vector<bool> binSel(n, true);
vector<int> minSteps(n, 0);
minSteps[n-1] = MinStep(X, Y, binSel, n);
/*cout << "minStep " << n << " : " << minSteps[n-1] << endl;*/
for (int i = n-2; i >= 1; i--)
{
pair<int, int> maxdistvec = heapdistVecsCountEq1.front();
/* cout << "==== " << i << " ======" << endl;
for (size_t s = 0; s < heapdistVecsCountEq1.size(); s++)
{
cout << heapdistVecsCountEq1[s].first << ' ' << heapdistVecsCountEq1[s].second << endl;
}
cout << "+++++++ " << endl;
for (int s = 0; s < n; s++)
{
for (int p = 0; p < vecsEdges[s].size(); p++)
{
cout << vecsEdges[s][p].first << ' ' << vecsEdges[s][p].second << ' ';
}
cout << endl;
}
cout << "----" << endl;
cout << maxdistvec.first << ' ' << maxdistvec.second << endl;*/
binSel[maxdistvec.second] = false;
minSteps[i] = MinStep(X, Y, binSel, i+1);
/* cout << "minStep " << i+1 << " : " << minSteps[i] << endl;*/
pop_heap(heapdistVecsCountEq1.begin(), heapdistVecsCountEq1.end(), PairIntIntCompareMin);
heapdistVecsCountEq1.pop_back();
/*cout << "==== " << i << " ======" << endl;
for (size_t s = 0; s < heapdistVecsCountEq1.size(); s++)
{
cout << heapdistVecsCountEq1[s].first << ' ' << heapdistVecsCountEq1[s].second << endl;
}*/
for (int j = 0; j < vecsEdges[vecsEdges[maxdistvec.second][0].second].size(); j++)
{
if (vecsEdges[vecsEdges[maxdistvec.second][0].second][j].second == maxdistvec.second)
{
vecsEdges[vecsEdges[maxdistvec.second][0].second].erase(vecsEdges[vecsEdges[maxdistvec.second][0].second].begin()+j);
break;
}
}
if (vecsEdges[vecsEdges[maxdistvec.second][0].second].size() == 1)
{
heapdistVecsCountEq1.push_back(make_pair(vecsEdges[vecsEdges[maxdistvec.second][0].second][0].first, vecsEdges[maxdistvec.second][0].second));
push_heap(heapdistVecsCountEq1.begin(), heapdistVecsCountEq1.end(), PairIntIntCompareMin);
}
vecsEdges[maxdistvec.second].pop_back();
}
for (int i = 0; i < n-1; i++)
{
cout << minSteps[i] << ' ';
}
cout << minSteps[n - 1] << endl;
}
return 0;
}
实验结果: