打比赛前先刷个虚拟赛热热身…
传送门
水题
题目意思是给出一个数组 可以使任意一个位置的数大小变成它后面的数
不限次数,请问是否可以使得最后数组元素之和是一个奇数
很简单 数组之和不是偶数就是奇数 奇数直接输出,偶数的话 只需要改变任意一个数的奇偶值就好即奇数->偶数 or 偶数->奇数 就可以使总和为奇数了
所以我们在输入的时候类和整个数组 ,再记录下相邻元素之间的差值是否有一个是奇数(因为一个数加上奇数才能改变奇偶)
和为奇数符合条件,和为偶数但差值存在奇数也符合条件
void solve()
{
int n=read();
int sum=0,f=0;
rep(i,1,n)
{
arr[i]=read();
sum+=arr[i];
if(i!=1&&abs(arr[i]-arr[i-1])%2==1)
f=1;
}
if(sum%2==1||f)
puts("YES");
else
puts("NO");
}
纯粹数学题…你可以理解为你起初有n瓶饮料,然后10个瓶盖可以兑换一瓶饮料,给出最初饮料数目,求出一共可以喝多少饮料…就是一个数学题…
void solve()
{
ll n=read();
ll sum=0;
while(n>=10)
{
sum=sum+n/10*10;
n=n/10+n%10;
}
printf("%lld\n",sum+n);
}
先吹一波pair真的好用!!
题目意思是给出一个操作序列,lrud对应左右上下,让你删减最短的连续片段,使得终点不变,可以的话输出最短片段的两个边界,反之输出-1
首先我的想法是开一个结构体lrud记录下每个位置前面l,r,u,d分别有多少,然后看一看是否有两个位置的l1-l2r1-r2且u1-u2d1-d2很麻烦。。。
然后越写越乱,而且复杂度感人…
之后参照了大佬的写法…我真是蒟蒻 我记录lr,u,d的相对关系就是看看有没有能删除的,也就是说有两个下标对应的点是不是在同一点!
我的思路是找lrud数量关系,大佬直接开个pair加map储存x,y来记录是否有地方重复到达过…即
if(mp[{x,y}]!=0&&mn>(i-mp[{x,y}]+1))
{
mn=i-mp[{x,y}]+1;
l=mp[{x,y}];
r=i;
}
直接判断这个点是否到达过,且符合条件时比较距离…
void solve()
{
int n=read();
int mn=n+1,l=0,r=n+1,x=0,y=0;
map<pii,int>mp;
mp[{0,0}]=1;
rep(i,1,n)
{
char ch=getchar();
if(ch=='L')
x--;
if(ch=='R')
x++;
if(ch=='U')
y++;
if(ch=='D')
y--;
if(mp[{x,y}]!=0&&mn>(i-mp[{x,y}]+1))
{
mn=i-mp[{x,y}]+1;
l=mp[{x,y}];
r=i;
}
mp[{x,y}]=i+1;
}
if(mn==n+1)
puts("-1");
else
printf("%d %d\n",l,r);
}
害…巨大的差距…
推荐写成 make_pair吧 尽量少用{}
题目意思简单
n个野怪,打野攻击力为a,辅助攻击力为b,两个人交替平a野怪,谁打死的野怪金币给谁(即最后一刀砍死的人)但是打野能开k次挂,每次开挂可以在辅助砍之前再砍一次,可以在同一时间多次开挂,每只野怪金币都是1,给出每只野怪的血量,请问打野最多可以获得多少金币
很明显贪心sort一下就好了,我们知道每只野怪死在谁手里不是看血量多少,而是看血量和两人攻击之和之间的关系
假设血量为num
num%(a+b)==0时 辅助砍死
num%(a+b)不等于0时,剩余血量小于等于a ,打野砍死
反之辅助砍死(打野可以开挂若干次强行砍死)
每只野怪金币一样,所以我们应该尽量把开挂次数用在需要开挂次数少的野怪身上,显然本身属于打野的耗费次数是0,反之就是
int res=num%(a+b)
res==0时res=b(退一回合)
所需开挂次数为 ceil(res/a) 剩余血量除于打野攻击力向上取整
所以sort条件为 res为0时 放后面,反之把res小的放前面
即
bool cmp(int x,int y)
{
int r1=x%(a+b),r2=y%(a+b);
if(r1==0||r2==0)
{
return r1>r2;
}
else
{
return r1<r2;
}
}
总代码是
bool cmp(int x,int y)
{
int r1=x%(a+b),r2=y%(a+b);
if(r1==0||r2==0)
{
return r1>r2;
}
else
{
return r1<r2;
}
}
int main()
{
n=read(),a=read(),b=read(),k=read();
rep(i,1,n)
{
arr[i]=read();
}
sort(arr+1,arr+n+1,cmp);
int ans=0;
rep(i,1,n)
{
if(k<=0)
break;
int res=arr[i]%(a+b);
if(res==0)
{
int cnt=ceil(b*1.0/a);
if(cnt<=k)
ans++;
k-=cnt;
}
else
{
if(res<=a)
ans++;
else
{
res-=a;
int cnt=ceil(res*1.0/a);
if(cnt<=k)
ans++;
k-=cnt;
}
}
}
printf("%d\n",ans);
return 0;
}