A题 Villages: Landlines
有三种类型的建筑:电站、电塔和房屋,建在x轴上。题目给出1个电站的坐标和n-1个房屋的坐标,他们分别有接收电力的半径范围,通过建立任意个电塔来连接电站给n-1个房屋通电。只要电塔在受电半径范围内就不需要电线连接,电塔和电塔之间必须用电线连接。要求出在将电塔和所有房屋连接起来的情况下所用电线的最小值。电塔个数不限。
思路:这道题最重要的一点在于房屋如果在电站的供电范围内,则它本身也可以看成是一个电站。将电站和房屋看成x轴上的线段,则线段与线段之间的空段长度即为要连接电线的长度。从这一点上来说,电站和房屋其实没有本质区别,只要将所有线段连接起来,具体哪个是电站,哪个是房屋对答案没有影响。所以存储时将它们一视同仁即可。由于题目中给出的坐标是中心点加半径的形式,实际编程中应该转换成左右端点的形式存储,并按左端点大右端点小的顺序排序。
#include <bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}nod[200005];
bool cmp(node &a,node &b){
if(a.l==b.l) return a.r>b.r;
return a.l<b.l;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int x,r;
cin>>x>>r;
nod[i].l=x-r;
nod[i].r=x+r;
}
sort(nod,nod+n,cmp);
int st,ed,wire=0;
for(int i=0;i<n;i++){
if(!i){
st=nod[i].l;
ed=nod[i].r;
}else if(ed<nod[i].l){
wire+=(nod[i].l-ed);
}
ed=ed>nod[i].r?ed:nod[i].r;
}
cout<<wire<<endl;
}
D题 Mocha and Railgun
思路:要找到AB的位置使得对应在墙上的弧长达到最大值,弧长最大可以转换成对应的弦长最大或者是圆心角最大,实际情况下是在AB平行于CQ连线时达到最大值,证明如下:
#include <bits/stdc++.h>
typedef long long ll;
const double pi=acos(-1);
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
double r;
cin>>r;
double XQ,YQ,d;
cin>>XQ>>YQ>>d;
double h=sqrt(XQ*XQ+YQ*YQ),ans;
if(h>=d){
ans=(acos((h-d)/r)-acos((d+h)/r))*r;
}else{
ans=(pi-acos((d-h)*1.0/r)-acos((d+h)*1.0/r))*r;
}
printf("%.10lf\n",ans);
//比赛的时候忘记换行了,离大谱
//记下来深刻检讨自己QAQ
}
}
G题 Lexicographical Maximum
题目:1到n中的所有数看成字符串,输出字典序最大的数。
思路:先看n的位数,如果n是一位数,那输出n本身。如果n的位数超过一位,将n与位数-1个9组成的数字作比较,输出字典序大的数。
#include <bits/stdc++.h>
using namespace std;
int main(){
string n;
cin>>n;
int len=n.size();
// cout<<len<<endl;
if(len==1) cout<<n;
else{
int f=0;
for(int i=0;i<n.size()-1;i++){
if(n[i]!='9'){
f=1;
break;
}
}
if(f){
for(int i=0;i<n.size()-1;i++){
cout<<9;
}
}else{
cout<<n;
}
}
}