太久没打比赛果然还是变菜了
这场div2 前三题都不难
传送门
A.FashionabLee
题意:正n边形,如果存在两条边,一条边平行于x轴,一条边平行于y轴,则输出yes,否则输出no
思路:我当时的想法是,我们先选择任意一条边与y轴平行,然后由于是正n边形,每个外角为
θ
=
360
n
\theta=\frac{360}{n}
θ=n360 。每条边就是往这个方向偏移了
θ
\theta
θ,那么要偏移到与x轴平行,则需要正好偏移
90
360
n
=
n
4
\frac{90}{\frac{360}{n}}=\frac{n}{4}
n36090=4n条边,也就是说n必须是四的倍数。
所以不上代码了,得到结论后判断是不是4的倍数即可。
B.AccurateLee
题意:给定一个01字符串S(只有0和1),如果出现10这种形式,即1在前面0在后面,那么你可以选择消除1或者0中间的某一个。给你一个字符,问你最短能消除成什么样子。
思路:我们需要知道,1和0中间的任意字符都是可以消除的。比方说1和0之间有很多1,那么利用一个0就可以全部消除了。所以我们只需要找到第一个1和 最后一个0即可。由于要求字典序最小,所以把这部分全部消除变成0即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int main(){
int n;
cin>>n;
while(n--){
int t;
cin>>t;
string s,str;
cin>>s;
if(t==1){
cout<<s<<endl;
continue;
}
int flag1=-1,flag2=-1;
for(int i=0;i<t;i++){
if(s[i]=='1'){
flag1=i;
break;
}
}
for(int i=t-1;i>0;i--){
if(s[i]=='0'){
flag2=i;
break;
}
}
if(flag2<flag1||flag1==-1||flag2==-1) cout<<s<<endl;
else {
str=s.substr(0,flag1)+s.substr(flag2,t-flag2);
cout<<str<<endl;
}
}
return 0;
}
C.RationalLee
题意: 你需要把n个数字分给k个人,你需要使得结果sum最大。sum的计算方法为每个人得到的数字最大值和最小值的和。如果某个人只有一个数字,那么就相当于这个数字*2
思路:这题其实不难。首先先把最大的数分给只需要分一个数字的人。再把其它数字排序后,每次给人分配一个最大的以及多个最小的。注意要讲需要讲人按需要分配的数量进行降序排列。这样才能保证小数尽可能地被前一个人包括进去了。我之前没有考虑这一点,所以少加了一个sort,导致WA2
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
int a[N],b[N];
bool cmp(const int a,const int b){
return a>b;
}
int main (){
int t;
cin>>t;
while(t--){
int n,k;
cin>>n>>k;
ll sum=0;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int index=n-1;
int st=0;
for(int i=0;i<k;i++){
cin>>b[i];
if(b[i]==1){
sum+=(ll)(a[index]+a[index]);
index--;
}
}
sort(b,b+k,cmp);
for(int i=0;i<k;i++){
if(b[i]==1){
continue;
}
sum+=(a[index]+a[st]);
st+=b[i]-1;
index--;
}
cout<<sum<<endl;
}
return 0;
}