这次练习赛中,刚开始提交时一直选错提交路径,选错编译语言,结果罚时太多了,一直是同答题数里的最后一名,这点以后要注意。
A-Engines
题目大意:n个点,任意几个点组合后得到的点距离原点的最远距离。
利用极角排序,将这些点看成与原点相作用的向量,然后根据平行四边行法则,两向量之间的角度相差越小,其复合得到的向量的长度越长。
#include<bits/stdc++.h>
using namespace std;
const int N=1E5+7;
struct stu{
double a,b;
bool friend operator <(const stu &x,const stu &y){
return atan2(x.b,x.a)<atan2(y.b,y.a);
}
}arr[N];
int nxt[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>arr[i].a>>arr[i].b;
for(int i=1;i<=n;i++) nxt[i]=i+1;
nxt[n]=1;
sort(arr+1,arr+1+n);
double ans=0;
for(int i=1;i<=n;i++){
double dx=arr[i].a;
double dy=arr[i].b;
ans=max(ans,arr[i].a*arr[i].a+arr[i].b*arr[i].b);
for(int j=nxt[i];j!=i;j=nxt[j]){
dx+=arr[j].a;
dy+=arr[j].b;
ans=max(ans,dx*dx+dy*dy);
}
}
printf("%.15lf\n",sqrt(ans));
return 0;
}
B-Consecutive Integers
简单题
#include<stdio.h>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int n,k;
while(cin>>n>>k){
cout<<n-k+1<<endl;
}
return 0;
}
C-ModSum
简单题,只要把最后一个数给牺牲点,前面的数都留下来,求和。
#include<stdio.h>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n){
cout<<1ll*(n)*(n-1)/2<<endl;
}
}
F-Monsters Battle Royale
要求找到最后一个活着的怪物的可能最终最小的生命值。就是不断辗转相减,也就是求最小公倍数的一种方法,所以当求最小公倍数就好。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int s[112345];
int main()
{
int i,n;
cin>>n;
for(i=0;i<n;i++){
cin>>s[i];
}
int ss;
ss=__gcd(s[0],s[1]);
for(i=2;i<n;i++){
ss=__gcd(ss,s[i]);
}
cout<<ss<<endl;
return 0;
}
G-Powerful Discount Tickets
刚开始写的时候,是想的每次都把,最大的数给作用一次,用Y次sort函数,可是一直超时。最后才通过优先队列给过了。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
//long s[112345];
priority_queue<int> q;
int main()
{
int i,n,m;
cin>>n>>m;
int k;
for(i=0;i<n;i++){
cin>>k;
q.push(k);
}
for(i=1;i<=m;i++){
k=q.top() ;
k/=2;
q.pop() ;
q.push(k);
}
long long ss=0;
while(!q.empty() ){
ss+=q.top() ;
q.pop();
}
cout<<ss<<endl;
return 0;
}
H-Attack Survival
简单题,都以k-q为底,之后的数在加一,最后遍历判断是否符合就好。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int ss[112345],s1[112345];
int main()
{
int n,k,q,i;
cin>>n>>k>>q;
for(i=0;i<q;i++){
cin>>s1[i];
}
for(i=0;i<n;i++){
ss[i]=k-q;
}
for(i=0;i<q;i++){
ss[s1[i]-1]++;
}
for(i=0;i<n;i++){
if(ss[i]>0) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
I-Lower
简单题,先把数都存起来,从最后向前开始遍历,满足条件a++,不然mx进行比较,用mx保留最大值。
#include<stdio.h>
#include<cstdio>
#include<iostream>
using namespace std;
int s[112345];
int main()
{
int i,n;
cin>>n;
for(i=1;i<=n;i++){
cin>>s[i];
}
int a=0;
int mx=0;
for(i=n-1;i>=1;i--){
if(s[i]>=s[i+1]){
a++;
mx=max(mx,a);
}
else{
mx=max(mx,a);
a=0;
}
}
cout<<mx<<endl;
}
J-Kleene Inversion
对最初的数组,输出每个数右边比他小的个数k(k+1)/2和每个数右边比他小的个数*(k-1)*k/2的累加和。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,n;
cin>>n;
char ss[111];
int a,b,y,x;
a=b=x=y=0;
while(n--){
scanf("%s",&ss);
if(ss[0]=='B'&&ss[strlen(ss)-1]!='A') b++;
else if(ss[strlen(ss)-1]=='A'&&ss[0]!='B') a++;
else if(ss[0]=='B'&&ss[strlen(ss)-1]=='A') y++;
for(i=0;i<strlen(ss);i++){
if(ss[i]=='A'&&ss[i+1]=='B')
x++;
}
}
if(y==0) cout<<x+min(a,b)<<endl;
else if(y!=0&&a==b&&a!=0) cout<<a+y+x<<endl;
else if(y!=0&&a==b&&a==0) cout<<x+y-1<<endl;
else if(y!=0&&a!=b) cout<<min(a,b)+x+y<<endl;
return 0;
}
M-AB Substrings
简单题,理解题意就很好做,分别求出,只有开头是b的个数,只有结尾是a的个数,同时满足开头b结尾a的个数,句中ab相连的个数。再算出关系式就能出解。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,n;
cin>>n;
char ss[111];
int a,b,y,x;
a=b=x=y=0;
while(n--){
scanf("%s",&ss);
if(ss[0]=='B'&&ss[strlen(ss)-1]!='A') b++;
else if(ss[strlen(ss)-1]=='A'&&ss[0]!='B') a++;
else if(ss[0]=='B'&&ss[strlen(ss)-1]=='A') y++;
for(i=0;i<strlen(ss);i++){
if(ss[i]=='A'&&ss[i+1]=='B')
x++;
}
}
if(y==0) cout<<x+min(a,b)<<endl;
else if(y!=0&&a==b&&a!=0) cout<<a+y+x<<endl;
else if(y!=0&&a==b&&a==0) cout<<x+y-1<<endl;
else if(y!=0&&a!=b) cout<<min(a,b)+x+y<<endl;
return 0;
}