B - Consecutive Integers
.给出两个整数N,K,求出从N个数中选择K个数的选法
求出N-K+1的值即可
#include<iostream>
using namespace std;
int main()
{
int n,k;
cin>>n>>k;
int ans;
ans=n-k+1;
cout<<ans<<endl;
return 0;
}
C - ModSum
给出一个n值求出n-1累加的值
即为n-1+(n-1)*(n-2)/2
#include<iostream>
using namespace std;
int main()
{
long long n,sum;
cin>>n;
sum=(n-1)+(n-1)*(n-2)/2;
cout<<sum<<endl;
return 0;
}
F - Monsters Battle Royale
给出n,再给出n个值,为怪兽的血量,攻击者不掉血,求出怪兽最小血量
运用辗转相除法,可以n个数最小的不可整除的数,就是求出他们的最大公约数
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int a[123456];
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
int gcd=a[0];
for(int i=1;i<n;i++)
{
gcd=__gcd(gcd,a[i]);
if(gcd==1)
break;
}
cout<<gcd<<endl;
return 0;
}
G - Powerful Discount Tickets
给出n,m值,n为个数,m为优惠券的个数
之后输入n个数,为买东西花的钱数,每次用y张优惠券可以用x/2*y(2的y次方)买到,
所以每次把最大值除以2,除够m次再累加就得出答案了
每次需要重新排序,所以运用优先队列,优先队列就是每次新存入一个数就会把他们按从大到小的顺序排列,队列顶端是最大值,这样会极大的节省时间
#include<bits/stdc++.h>
using namespace std;
priority_queue<int> q;//设置优先队列,进入优先队列都会从小到大排好
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
int t;
cin>>t;
q.push(t);//进入队列
}
while(m--)
{
int flag=q.top();
flag/=2;
q.pop();
q.push(flag);
}
long long sum=0;
while(!q.empty())
{
sum+=q.top();
q.pop();
}
cout<<sum<<endl;
return 0;
}
H - Attack Survival
给出n,k,q
n :有n个成员
k:每个成员k分
q:一共有q个题
之后q个值就是第i个成员答对,除了第i个其余的分数都要减一,如果最后的分数小于等于0输出no否则yes
先进行记录第i个成员答对的次数,最后结果就是初始成绩减去总题数q加上第i个值出现的次数
#include<bits/stdc++.h>
using namespace std;
int a[123456];
int flag[123456];
int main()
{
int n,k,q;
cin>>n>>k>>q;
for(int i=0;i<q;i++)
{
int t;
cin>>t;
a[t]++;
}
for(int i=1;i<=n;i++)
{
flag[i]=k;
}
for(int i=1;i<=n;i++)
{
flag[i]=flag[i]-q+a[i];
if(flag[i]<=0)
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
return 0;
}
//h
I - Lower
记录每一个点可以移动的次数,进行排序,输出最大值即可
#include<iostream>
#include<algorithm>
using namespace std;
int a[123456];
int flag[123456];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(i==0)
flag[0]=0;
else
{
if(a[i]<=a[i-1])
flag[i]=flag[i-1]+1;
else
flag[i]=0;
}
}
sort(flag,flag+n);
cout<<flag[n-1]<<endl;
return 0;
}
J - Kleene Inversion
对一列数字进行重复n次,求出第i之后有几个数小于a[i]
代码有详细注释
#include<iostream>
using namespace std;
int a[12345];
int flag[12345];
long long mod=1e9+7;
int main()
{
long long n,k,sum1=0;
cin>>n>>k;
k=k%mod;
for(int i=0;i<n;i++)
{
cin>>a[i];
for(int j=0;j<i;j++)
if(a[j]<a[i])
flag[i]++;//记录第i个数 大于之前从0到i-1的有几个
}
//section one
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
if(a[i]>a[j])
sum1++;//i从1到倒数第二个,记录从第i+1个数开始第i个数小于第i个的有几个
}
long long t=(k+k*(k-1)/2)%mod;//从1到k累加
sum1=sum1*t%mod;//计算 重复k次后按照顺序有几个数值
//scetion two
long long sum2=0;
for(int i=0;i<n;i++)
{
sum2+=flag[i];//重复之后第i个之前比i小的数的累加
}
t=((k-1)+(k-1)*(k-2)/2)%mod;//从1到(k-1)的累加
sum2=sum2*t%mod;
long long sum=(sum1+sum2)%mod;//求和
cout<<sum%mod<<endl;
return 0;
}
M - AB Substrings
需要考虑多种情况
#include<iostream>
#include<cstring>
using namespace std;
string str[12345];
int main()
{
int n,flag=0,flag1=0,flag2=0,flag3=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>str[i];
for(int i=0;i<n;i++)
{
int len=str[i].length();
for(int j=0;j<len-1;j++)
{
if(str[i][j]=='A'&&str[i][j+1]=='B')
flag++;//字符串中间存在“AB"
}
if(str[i][len-1]=='A'&&str[i][0]!='B')
{
flag1++;//尾部“A”头部不是“B”
}
if(str[i][0]=='B'&&str[i][len-1]!='A')
{
flag2++;//尾部不是“A”头部是“B”
}
if(str[i][len-1]=='A'&&str[i][0]=='B')
flag3++;//尾部是“A”头部是“B”,记录防止成环
}
if(flag1!=flag2)
flag+=flag3+min(flag1,flag2);//当可能出现成环现象时
else
{
if(flag3!=0&&flag1==0)
{
flag+=flag3-1;//当头部为B时尾部必为A
}
else if(flag3!=0&&flag1!=0)
{
flag+=flag3+flag1;//
}
else
flag+=flag1;
}
cout<<flag<<endl;
return 0;
}