昨晚的一场牛客周赛,上了100分,但还是只能做不到四题,AB就不说了,觉得C这题挺好的,单独写一下题解吧~
目录
C题
题面描述
思路分析
其实思路很好想,主要是借这一题我们要学会一些常见的代码实现,我们可以从题目中看到有m组坐标且不重复,那我们先开一个pair读入每一组数据,当xi = xj 或者 yi = yj 时可以连线,要求距离的最大值,那我们其实可以很自然的联想到map,但是这次要开的map不是存入两个int了,而是存入每一组横坐标或者纵坐标相同时,对应的纵坐标和横坐标,所以应该map应该开一个<int,vector(int)>,用数组来存当一个坐标值相等时,所有每一组的另一个坐标值,然后我们找到数组的最大值和最小值,相减比较找出最大的值即可,即为最终的答案,下面我们看一下代码怎么写——
另外需要注意的是我们在求数组里的最大值和最小值时,第一种方法我们可以直接sort排序一下
直接最右边元素和最左边元素相减就行了,或者我们也可以用*min_element和*max_element得出数组的最大元素和最小元素
代码实现
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <climits>
#include <iomanip>
#include <cmath>
#include <string>
#include <vector>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
//int a[N];
typedef pair<int,int> PII;
PII p[N];
unordered_map<int,vector<int>> row_mp;
unordered_map<int,vector<int>> col_mp;
void solve()
{
int n,m;
cin >> n >> m;
for(int i = 1; i <= m; i++) cin >> p[i].x >> p[i].y;
for(auto &c : p)
{
int a = c.x;
int b = c.y;
row_mp[a].push_back(b);
col_mp[b].push_back(a);
}
int len = 0;
for(auto &c : row_mp)
{
// const vector<int>& positions = row.second;
if(c.y.size() > 1)
{
/* int min_pos = *min_element(c.y.begin() , c.y.end());
int max_pos = *max_element(c.y.begin() , c.y.end()); */
sort(c.y.begin() , c.y.end());
len = max(len , c.y[c.y.size() - 1] - c.y[0]);
}
}
for(auto &c : col_mp)
{
if(c.y.size() > 1)
{
/* int min_pos = *min_element(c.y.begin() , c.y.end());
int max_pos = *max_element(c.y.begin() , c.y.end());
len = max(len , max_pos - min_pos); */
sort(c.y.begin() , c.y.end());
len = max(len , c.y[c.y.size() - 1] - c.y[0]);
}
}
cout << len << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
/* int t;
cin >> t; */
while(t -- ) solve();
return 0;
}
*max(min)_element用法
这里我补充一下*max(min)_element用法 ,一样方便后续复习食用,max_element( ) 的函数返回值是个指针,对应的是最大值所对应的位置,*max_element则对应最大值的具体数值,比设置临时变量for循环遍历求解最大(小)值要高效。直接贴个代码就看明白了——
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
int a[] = {-5,-3,-3,-2,7,1}, b[] ={-10,-5,3,4,6};
cout << *max_element(a, a + 6) << endl;
// cout << *max_element(a, a + sizeof(a)/sizeof(int)) << endl;
cout << *min_element(b, b + 5) << endl;
vector<int> c{-5,-3,-3,-2,7,1}, d{-10,-5,3,4,6};
cout << *max_element(c.begin(), c.end()) << endl;
cout << *min_element(d.begin(), d.end()) << endl;
return 0;
}
输出:
D题
题面描述
思路分析
本题也是一个思维题,维护一个集合[1 ~ X],表示这个集合能凑出1 - X中任意一个数,首先让星星数组从小到大排序,赛时这题只过了3/5,还是没处理到位,比赛后来看题解是dp的一种想法,如果sum表示的是小于等于sum的数都可以表示出来,那枚举到ai的时候,sum到sum + ai − 1都可以表示出来。
代码实现
#include <iostream>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;
void solve() {
int n;
cin >> n;
std::vector<int> a(n + 1);
for(int i=1;i<=n;i++){
std::cin>>a[i];
}
std::sort(a.begin() + 1, a.end());
int sum = 0;
for (int i = 1; i <= n; i++) {
if(sum >= a[i] - 1) {
sum += a[i];
}
}
if(sum >= n) cout << "Cool!" << endl;
else cout << sum + 1 << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) solve();
return 0;
}
身边的同学考研的考研,考公的考公,而我还在热爱算法竞赛的道路上独自流浪,下一场线上赛就是这周六(9月21日)了,暂时打算这星期就不碰了,周五学校ACM算法协会还要招新,身为会长这学期也是很忙的,慢慢来吧,这星期去刷刷考研数学和准备一下软考了~~~
我的生活确实充斥着沉闷和平凡,我想,是时候做一些事情了,于是我就去做了——