链接: https://codeforces.com/contest/1283/problem/D
题意:给定n个不同的整数点,让你找m个不同的整数点,使得这m个点到到这n个点最小距离之和最小。
思路:贪心一下,首先每个点的x+1和x-1两个坐标到这个点的距离是最短的,之后是x+2,x-2,再之后是x+3,x-3,那么可以想到bfs,首先把n个点存入队列中,找与他们距离为1的点,之后再bfs距离为2的点,如此这个过程直到找到m个点.
AC代码:
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 const int mod = 1e9+7; 10 const int maxn = 2e5+5; 11 typedef long long ll; 12 queue<pair<int,int> > q; 13 map<int,bool> vis;//用map记录是否访问过 14 vector<int> v; 15 int main(){ 16 int n,m;cin>>n>>m; 17 while(n--){ 18 int t;cin>>t; 19 vis[t] = 1; 20 q.push({1,t+1}),q.push({1,t-1}); //首先存距离为1的点 21 } 22 ll ans = 0; 23 while( m>0 && !q.empty() ){ 24 pair<int,int> cur = q.front() ; 25 q.pop() ; 26 if(vis[cur.second]!=1){//如果没有遍历过 27 m--; 28 v.push_back(cur.second ); 29 ans+=cur.first; 30 vis[cur.second] = 1; 31 if(vis[cur.second+1] != 1) q.push({cur.first+1,cur.second+1});//距离+1,入队列 32 if(vis[cur.second-1] != 1)q.push({cur.first+1,cur.second-1}); //同上 33 } 34 } 35 cout<<ans<<endl; 36 for(int i = 0;i<v.size() ;i++){ 37 cout<<v[i]<<" "; 38 } 39 return 0; 40 }