第一次参加ICPC,了解了ICPC的题型和比赛流程及比赛规则。
这次和团队小伙伴一共做出两道题,赛后又去了解了一道题,下面是三道题的题解及代码。
Problem F. Land Overseer
这道题的大概意思就是从O(0,0)到A(a,b)再到B(2a,0)的最短距离,且到每个点的距离最多不超过R就表示到达该点。
解题思路:先计算O(0,0)点到A'(a,b - R)的距离,但是此处有个坑,如果R > b,则只需计算O(0,0)到A''(a,0)的距离(即b)就行了,然后判断A'/A''到B’(2a - R,0)的距离。由于题目限制,故不用考虑2a < R 的情况。
代码如下:
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main()
{
int T; //T组数据
cin>>T;
for(int i = 1; i <= T; i++)
{
double a,b,R,len = 0;
cin>>a>>b>>R;
//R > b 时只需判断O到B的距离即可到达O、A、B三点
if(R > b) len = 2 * a - R;
//否则三点组成一个等腰三角形
else len = 2 * (sqrt(pow(a,2) + pow((b-R),2))) - R;
cout<<"Case #"<<i<<": ";
if(T == 0) cout<<fixed<<setprecision(2)<<len;
else cout<<fixed<<setprecision(2)<<len<<endl;
}
return 0;
}
Problem H. Mesh Analysis
这题的题意大概就是找到与点id共平面和共线的点的id以及包含id点的操作的id。
第一行输入整数N和整数M,接下来N行,每行输入四个整数,分别为点的id和该点的x、y、z坐标(其实这N行没有实际作用,可以忽略)。接下来M行输入四个或者五个整数,第一个数为点的id,第二个数为102或203,若为102则接下来输入两个整数分别代表线段的两个端点,若为203则接下来输入三个整数分别代表三角形的三个点。接下来输入一个L,接下来L行表示需要查询的id。
输出L*3行,没三行第一行代表查询的id,第二行代表与点id共线或者共面的点的id,第三行代表含有点id的操作id。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<ll,set<ll> > belongel;
unordered_map<ll,set<ll> > belongpo;
int main() {
int n,m;
cin >> n >> m;
for (int i = 0;i < n;++i) {
ll id;
double x,y,z;
cin >> id >> x >> y >> z;
}
for (int i = 0;i < m;++i) {
ll id,idx;
cin >> id >> idx;
if (idx == 102) {
ll x,y;
cin >> x >> y;
belongpo[x].insert(y);
belongpo[y].insert(x);
belongel[x].insert(id);
belongel[y].insert(id);
}else{
ll x,y,z;
cin >> x >> y >> z;
belongpo[x].insert(y);
belongpo[x].insert(z);
belongpo[y].insert(x);
belongpo[y].insert(z);
belongpo[z].insert(x);
belongpo[z].insert(y);
belongel[x].insert(id);
belongel[y].insert(id);
belongel[z].insert(id);
}
}
int L;cin >> L;
bool fir = 1;
while (L--) {
if (fir){
fir = false;
}else{
cout << endl;
}
ll id ;cin >> id;
cout << id << endl;
bool _ = true;
//point
set<ll> &outt = belongpo[id];
if (outt.empty()){
//cout <<"[]\n";
cout<<"[]"<<endl;
_ = false;
}
if (_){
cout << '[';
for (auto it : outt) {
if (it != *outt.begin()) cout << ',';
cout << it;
}
//cout << "]\n";
cout<<"]"<<endl;
}
_ = true;
set<ll> &oute = belongel[id];
if (oute.empty()) {
cout << "[]";
_ = false;
}
if (_){
cout << '[';
for (auto it : oute) {
if (it != *oute.begin()) cout << ',';
cout << it;
}
cout << ']';
}
}
return 0;
}
Problem I. Neighborhood Search
这道题在做的时候其实没看懂题目,看输入输出案例就猜是将第一行逆序排序,然后找出与第二行相差不超过第三行的数并依次输出。后面下来翻译了一下题目意思也差不多。
这道题看题目|S| 100000,果断采用桶排序
代码如下:
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
int n=0,a[100005];
int main()
{
stringstream ss;
string s;
getline(cin,s);
ss<<s;
int t,x,y;
while(ss>>t)
a[n++]=t;
sort(a,a+n);
reverse(a,a+n);
cin>>x>>y;
for(int i=0;i<n;i++)
if(abs(a[i]-x)<=y)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}