【CSP-J 2021】1.分糖果
此题考查的主要是数学归纳能力,与前几年套路一样,都是先水后难
整合题意:在[L,R]内找到一个x,使x%n最大
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,l,r,i,maxx=0,k;
scanf("%d %d %d",&n,&l,&r);
k=r/n*n-1;
if(k>=l)
printf("%d",k%n);
else if(r/n==1)
printf("%d",r%n);
else
{
for(i=k+1;i<=r;i++)
maxx=max(maxx,i%n);
printf("%d",maxx);
}
return 0;
}
【CSP-J 2021】2.插入排序
核心知识点:双向索引,对排序的理解,对时间复杂度的理解
用时间复杂度来分析题目,查询上限200000,n上限8000,常规做法每轮查询都排序时间复杂度200000* 8000* 13,肯定时间爆掉了,
再看修改数据5000,5000* 8000复杂度是跑不掉的,那外面也套不了什么优化了,所以这题时间复杂度就是5000* 8000+(200000-5000),命令2是O(1)
这题就是用rank和sa数组
具体做法
1.读入数据,排序,生成rank和sa数组
2.碰到2命令直接输出,碰到1命令,修改arr中的值,然后判断是向前做一趟排序,还是向后做一趟排序,同时改变sa和rank的值,change函数实现
注:sa[i]=j表示排序后的第i个元素在原数组的第j个,rk[i]=j表示原数组的第i个元素在排序后的第j个
#include<bits/stdc++.h>
using namespace std;
typedef struct node
{
int id,v;
bool operator < (const struct node & t)const
{
if(v==t.v)
return id<t.id;
return v<t.v;
}
}NODE,*PNODE;
NODE arr[8005];
int sa[8005],rk[8005],n;
void change(int id,int v)
{
int k=rk[id];
bool s;
if(v==arr[k].v)//不变就直接返回
return;
s=arr[k].v>v;//s用来判断是比原值大了还是小了
arr[k].