2021 CSP-J复赛 我的备战与游记

备战

2021.10.18

下午班主任找到我,告诉了我一个消息——这一周的下午和晚修全部上信息

我当时十分高兴,但三秒后....

妈耶,我文化课要垮了QAQ

到机房时,老师开始讲强连通分量,太监(tarjan)算法

我傻掉了QAQ

(初赛都这么变态,base64四毛子,复赛怕会普及出黑题.....)

后来晚上初一几个自学三角函数,这是我奋斗的足迹


2021.10.19

在Panda的帮助下搞懂了太监算法,然后做比赛

提高难度,我们进复赛的四个初一全部西内

当中最高是教授和某兔子爱好者,切了一题105

我和王梓烨垫底了QAQ

有一题我以为是树状数组,结果是模拟,痛失15分


不过没事,我们与其他初一又一起做了牛客的模拟赛

(当然并不是同步赛)

然后....全员200可还行

我突然觉得一等无望了....


晚上突然对魔法猪学院起了兴趣.....

72,A* 过不了啊!!

于是暂时放下,安心复习


2021.10.20

又做了做魔法猪学院

发了个贴

想不到有个犇犇告诉我有A* 能过的

秒切


偶然发现中山原来有这么多普及红名大佬?我被暴踩


搞了一会博客园,投入到学习中

老师开了几个复习专题,我先做了高精,切了几道

数据结构,我不会银河英雄传说,我太菜了

在这里复习一下种类并查集

比如食物链

我们用x与y+n有关系表示x吃y

x与y+2*n表示y吃x

这样去连,到时候判断即可

好的,然后是数论,exgcd忘干净了,赶紧复习

推了几次式子,会求\(ax+by=1\)了,不会\(ax+by=c\)


2021.10.21

上午刚好有节信息课,拿来复习

欧拉函数搞懂了!!!又A两道,Great!

复习欧拉函数


中午去做核酸,和王梓烨和教授聊天,不亦乐乎

(我还说我是IFW——International Feet Washing (世界洗脚大赛)的冠军哈哈哈)


下午继续刷题

Panda梅开二度,教我\(ax+by=c\),Orz

复习了哈希

好紧张呀,加油!!!


2021.10.22

参加模拟赛,倒数第二

重测一次,倒数第一

难受,晚饭没吃

然后在vjudge做练习,还是太监算法

我被虐菜

晚上回班收拾作业,好...多...

路上看见一个同学,说,只要我AK了,就请他喝炖汤

怎么可能(AK)?

比赛当日

早上

\(5:50\)醒了,去吃早餐

\(6:45\)出发

\(7:25\)左右到了

想进去看看,结果XC不让进,于是各个学校的OIer就闲聊

线下见面

见到了洛谷上两个大佬!!

之前在洛谷上约好的,终于见面了

非常尬:

“你平常登洛谷吗”

“哦,你是xx”

“啊哈啊哈”

“额哈额啊哈”

正文

开始前上了个厕所,结果xc大声说:

“你干嘛进进出出的”

“我...才出去一次”

然后xc对考官说:

“这种出去的一定要好好查一下”

我 被 搜 身

好强的压迫感....

比赛开始后,老师让我们输密码(结果老师自己打错了

谢谢JZ提供了一个卡死的Linux模拟机,还没windows稳定....


第一题不是很确定,没想出来(我太菜了)

然后打了一个能过样例的公式,先做其他题

第二题真就题如其名,

一开始以为是树状数组,浪费10分钟

其实不是很难,个人认为最简单(Because 不会第一题)

做完第二题,出去喝了杯牛奶,回去做第三题

第三题其实就是输入恶心,

我调了50分钟的输入

结果灵光一闪————不就scanf的妙用吗

但为了判断前导零,要用sscanf

然后半个小时切了

这时差不多\(11:15\)

啊!!要不是这里浪费了太多时间,第一题我可能就调出来了!!!!

第四题我用了链表做,节省时间

感觉会超时.....

(P.S:我有一个朋友说他用并查集,不知道怎么做的,样例全过Orz)

只对了一下样例,没来得及对拍

然后看第一题,改了一下,搞了一个对拍

对到\(11:45\),老师收各种东西,然后去打文操了

发现第二题调试没删,差点爆零....


比赛后

回家了

测了一下第四题,70分TLE QAQ

一等没了

结果一测其他题:\(100+100+100+70=370\)?!

其他网站都差不多,第四题不同

xx小灵通:第四题50,其他AC

计蒜客:第四题90,其他AC

诡异啊!!!大佬都说我第一题公式不对,对拍也不对,但各个网站都过了?

如果准的话,一等了.....(2021.10.30:说的真准)

估计实际第一题70左右(2021.10.31:其实是60)

赛后总结与讲解

2021.10.30:Ohhhhhh!!360!!

感谢教练!!

三年了!!我出息了!!

简单总结

题目名 得分 个人定位 检查 暴力 数据全过
candy \(100\) 数学,思维 YES NO YES
sort \(100\) 时间复杂度,排序,模拟 YES NO YES
network \(100\) 模拟,哈希,输入技巧 YES NO YES
fruit \(60\) 链表,模拟 YES YES MAYBE

一开始先把题都看了,所以没有因小失大

第二,第三题发挥稳定,但第三题输入想了\(50min\),是一个巨大的失误

第一题未能推出正解,对排每20个测试点错1个

但是,数据,它!!过!!了!!

第四题暴力顺利水到60分

Candy

小结

第一题未能推出正解,对排每20个测试点错1个

但是,数据,它!!过!!了!!

(感谢CCF出了这么水的数据点!!)

题解

我还是认为我会被强数据hack,不拿自己的trash思路忽悠人了

这是别的犇犇的思路:

其实我们想,最优情况是\(n-1\)——再拿一个就又要分了

但有时不足\(n-1\),我们拿不到那么多,怎么办呢?

我们\(r\)就好了,

因为拿不到\(n-1\)就说明\([ l , r ]\)能拿到的是一个\([1,n-2]\)的一个子区间

也就是说,越往后越优

所以保证拿\(r\)个是最优解

(我考场没想出来QAQ)

参考代码

#include<bits/stdc++.h>
using namespace std;
long long n,l,r;
int main()
{
    cin>>n>>l>>r;
    if(l%n+r-l>=n)//如果能拿n-1个
    {
        cout<<n-1;
    }
    else
    {
        cout<<r%n;
    }
}

赛时代码(可能有错)

只可意会,不可言传

很垃圾,自己看吧.....

#include<stdio.h>
#include<bits/stdc++.h> 
using namespace std;
long long n,l,r;
inline long long read()//手打小垃圾快读
{
	char c=getchar();
	int f=1;
	long long sum=0;
	while(c!='-'&&(c<'0'||c>'9'))c=getchar();
	if(c=='-')
	{
		f=-1; 
		c=getchar();
	} 
	do
	{
		sum=(sum<<3)+(sum<<1)+c-'0'; 
		c=getchar();
	}while(c>='0'&&c<='9');
	return sum*f;
}
int main()
{
	n=read(),l=read(),r=read();
	long long mn=l/n,mx=(l+n-1)/n;
	mn*=n,mx*=n;
	long long ans=r-mn,ans2=r-mx;
	//printf("%d %d %d\n",mn,ans,r); 
	if(ans>=n||ans2>=n)
	{
		printf("%d",n-1);
	}
	else
	{
		printf("%d",max(ans,max(0*1ll,ans2)));
	}
}

优点:

  • 该放手时就放手,在作不出时换题,保证了比赛的 节奏稳定 ,是一个 很好的习惯

  • 最后回来对排,但未找出正解,对排是个好习惯

缺点

  • 思维题能力欠缺 ,尤其是这种打卡题

Sort

小结&题解

考前蒙对了,猜中有 时间复杂度 的题

各位想想,有三种做法(正常的)

第一种

暴力,每次修改排一次序,用一个数组记录

这个数组的第x项表示第x项排序后到了哪里,查询\(O(1)\)

复杂度约为:

\(O(mnlog_n+m)\)

但修改最多5000次,所以更正为

\(O(5000nlog_n+m)\)
显然TLE

第二种

对于修改,直接改,\(O(1)\)

对于查询,找一遍所有小于它的\(O(n)\)

复杂度:

\(O(nm)\)甚至慢过暴力

正解:第三种

先用sort排,

然后对于每次修改,去重新定位这个修改的数,跟插入排序差不多,复杂度\(O(n)\)

查询,只需要输出准备好的一个数组,同做法一,复杂度\(O(1)\)

注意看题,修改最多\(5000\),盲猜一堆人以为我这个修改会超,因为他们以为极端数据会修改\(200000\)次,

复杂度:

\(O(nlog_n+5000n+m)\)不会超

所以要 好好看题 呀!!!

话说貌似每年的第二题都要估算时间复杂度....大家可以专门练一下这种题

参考代码:

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int num,no;
}b[8005];
long long x,y,z,n,m,a[8005],c[8005];
int cmp(node x,node y)//如果相等,比较编号
{
	if(x.num==y.num)
	{
		return x.no<y.no;
	}
	return x.num<y.num;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[i].num=a[i];
		b[i].no=i; 
	} 
	sort(b+1,b+n+1,cmp); 
	for(int i=1;i<=n;i++)
	{
		c[b[i].no]=i;//预处理数组
	}
	b[n+1].num=1e10,b[0].num=-1e10;//用来返回的边界
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		if(x==2)
		{
			cout<<c[y]<<endl;
			continue;
		}
		if(x==1)
		{
			cin>>z; 
			b[c[y]].num=z;
			for(int j=c[y];j<=n;j++)//调整位置
			{
				if(b[j].num>b[j+1].num||(b[j].num==b[j+1].num&&b[j].no>b[j+1].no))
				{
					swap(b[j],b[j+1]);
					c[b[j].no]--;
				}
				else
				{
					c[y]=j;
					break;
				}
			}
			for(int j=c[y];j>=1;j--)//注意两边都要试
			{
				if(b[j].num<b[j-1].num||(b[j].num==b[j-1].num&&b[j].no<b[j-1].no))
				{
					swap(b[j],b[j-1]);
					c[b[j].no]++;//交换后,预处理数组也要更改
				}
				else
				{
					c[y]=j;
					break;
				}
			}
		}
	}
}

优点:

  • 仔细看题,找出解题的关键要素,不漏每个细节,这也是我能AC本题的原因

  • 百折不挠,认真调试,在比赛时,有一个好的心态,去进行复杂的调试

  • 在发现正解,有敢于推翻旧解的心态,我发现正解后立刻删除了旧代码,毫无感情

缺点

  • 一言不合暴力,开局打了一个树状数组+离散化,显然不对

Network

小结&题解

这道题是可以\(20min\)搞定的水题

But我浪费了很多时间

难点是输入

但仔细想想也不难

单独发在博客了,会投稿题解

放个网址:

博客园:THIS

Luogu博客:THIS

优点:

  • 无,如果非说有,知道的函数(sscanf)救了自己一命

缺点

  • 花了太多时间,\(1h10min\)本场比赛最大失误
  • 在耗费大量时间时,没有及时跳题,与第一题相反

Fruit

小结

打了暴力
用链表模拟

赛时代码

#include<bits/stdc++.h>
using namespace std;
int n,s,t,sum;
struct node
{
	int num,l,next;
}a[200005];
inline long long read()
{
	char c=getchar();
	int f=1;
	long long sum=0;
	while(c!='-'&&(c<'0'||c>'9'))c=getchar();
	if(c=='-')
	{
		f=-1; 
		c=getchar();
	} 
	do
	{
		sum=(sum<<3)+(sum<<1)+c-'0'; 
		c=getchar();
	}while(c>='0'&&c<='9');
	return sum*f;
}
int main()
{
	n=read();
	s=1,t=n;
	for(int i=1;i<=n;i++)
	{
		a[i].num=read();
		a[i].l=i-1;
		a[i].next=i+1;
	} 
	while(sum!=n)
	{
		int k=-1;
		for(int i=s;i<=t;i=a[i].next)
		{
			if(a[i].num!=k)
			{
				k=a[i].num;
				sum++;
				cout<<i<<' ';
				a[a[i].next].l=a[i].l;
				a[a[i].l].next=a[i].next;
				if(i==s)
				{
					s=a[i].next;
				}
				if(i==t)
				{
					t=a[i].l;
				}
			}
		}
		cout<<endl;
	}
} 

正解

其实大概想到了,但没时间打。

再加一个链表,每项表示一个“水果链”,

每次直接跳下一个水果链,快很多。

优点:

  • 能水一分是一分,一种良好的比赛态度

缺点

  • 正解很好推,但时间不够(第三题的锅)

总结

根据上述,下次要做到:

  • 该放手时就放手,在作不出时换题
  • 强化思维题能力
  • 仔细看题,找出解题的关键要素,不漏每个细节
  • 百折不挠,认真调试
  • 在发现正解,有敢于推翻旧解的心态
  • 不要一言不合暴力
  • 能水一分是一分
  • 还是要说——诚信考试!!!
posted @ 2021-10-21 20:19  DengDuck  阅读(617)  评论(6编辑  收藏  举报