放在前面:各位同学一定要好好复习初赛……不要像我一样初赛都没过……
1.P7909
作为第一题……肯定不会很难(我还是卡了一下TAT)
可以想到输出的结果一定是 0~(n-1)
关键在于是判断输出n-1还是其他
- L到R之间的区间超过n 输出(n-1)
- L到R之间的区间小于n 输出最大解(r%n)
上代码:
#include
using namespace std;
int n,l,r,a,b;
int main()
{
cin>>n>>l>>r;
a=l/n;
b=r/n;
//判断区间
if(a==b) cout<
理解一下应该不太难(相比于其他题解做法,这个要讨论的情况不会太多,不容易出错)
2.P7910
这道题的题目理解相对难一(hen)点(duo)
关键在于选择排序是个稳定排序(复习一下初赛知识——稳定排序有:希尔选择快速堆
还有就是解决超时问题
H 老师不喜欢过多的修改,所以他保证类型 1 的操作次数不超过 5000。
所以我们选择对类型1下手……!
关键点:操作类型1时顺便排序
还有就是一些……奇奇怪怪的错误
代码(虽然代码写的繁琐,但是思路还是很明确的……其实是我太菜):
#include
#include
#include
using namespace std;
int n,m,kind,x,v,ans;
struct number
{
int a,ans;
}p[8005],b[8005];//b数组是为了方便转换
//p.a保存原数组
//p.ans是保存排序后的下标
//b为排序后的数组
//b.ans是排序前的下标(用于转换)
bool cmp(number x,number y)//sort
{
if(x.a!=y.a)
return x.ay.ans;
return x.a>y.a;//稳定排序下标也需要比较
}
bool l(number x,number y)//十分繁琐的判断是否可以交换
{
if(x.a==y.a) return x.ans1;k--)
{
if(l(b[k],b[k-1]))//码代码小tip:当判断十分繁琐……再用一个函数写也不是不可以
//(我这里调了好久)
swap(b[k],b[k-1]);
}
for(int i=1;i<=n;i++) p[b[i].ans].ans=i;//转换说的就是这里
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&p[i].a),b[i].a=p[i].a,b[i].ans=i;//转换
sort(b+1,b+1+n,cmp);//开头那个排序
for(int i=1;i<=n;i++) p[b[i].ans].ans=i;//再转换
for(int i=1;i<=m;i++)
{
scanf("%d",&kind);
if(kind==1)
{
scanf("%d%d",&x,&v);
//核心代码排序(其实这里可以用一个sort直接解决【如开头那个排序】……
//为什么不用后文会提到
if(v>p[x].a)
right();
if(v
回到排序的问题(为什么不用sort直接解决?)
当然是因为超时呀……!
思考一下:
其实b数组一直都是有顺序的
当你改变某个元素的值时……你只需要判断它去那个位置就ok了
所以就有了那段繁琐的 left 和 right
其实我的代码是比较……丑陋的(蒟蒻)
3.P7911
这道大模拟着实没有意义……直接看代码吧(可以说比较清晰了)
写了 的代码:
#include
#include
#include
#include