【Day4】【纪中OJ】2019.1.26大型被虐C组模拟赛(游记+题解)

这篇博客记录了作者参加2019年某一天的C组在线编程比赛的经历,包括上午的比赛难易度、下午的复习讨论和晚上的趣事。作者详细介绍了比赛过程中的感受,以及遇到的技术问题,如OJ服务器卡顿。此外,还分享了四道比赛题目(T1到T4)的题解,涉及连续自然数和、简单游戏、幸运票和抄书问题,分别给出了算法思路和样例解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


游记

Morning

【Before 8:00】依然起得很晚,以至没有早餐吃了555。在洛谷打了卡,大吉(请一定要记住这个大吉)。然后发现今天的比赛竟然7:40就开始了。。。
【Before 10:00】今天C组的题目依然很难。

题目 做法
连续自然数和 暴力枚举
简(he)单(bing)游(guo)戏(zi) DFS+剪枝
幸运票 递推+高精
抄书 二分

【Before 11:00】 OJ被卡爆了!2个小时!大家都无心做题,都在FB!!!
【Before 12:00】 分数出来了。
得分:100+0+0+50=150 **OJ!评测不了!害我2题爆0
还有第4题,因为少打了一个0挂了一半的点嘤嘤嘤
大佬+蒟蒻本人排行榜

姓名 得分 名次
PRJ 180 第四名
LFY 170 第六名
蒻K 150 第七名
CNH 100 第十二名

被众大佬吊打中ing。。。
放学的时候,大家还在FB。此时XC来了,因为XC听到有人报信,大家就都被D了一顿。XC走后,大家都在凉意中,有个人说了句“XC…”。结果被刚想走进来的XC听见了他的外号,于是大家又被D了一顿(巨凉)幸好我那时在上厕所(逃)
【Before 12:30】 午饭好多人啊~~~~~~·我感觉我排了半小时队。。。。。。


Afternoon

【Before 14:00】 又FB了一中午,竟然有小学生说Fuck Girl On the bed 很好玩。。。。。。(总结:小学生=甘地)
【Before 16:00】讲课中。。。难度:第一题<第四题<第三题<第二题
【Before 17:00】当时教室超级吵,XC又把我们D了一顿,还说了一句真理:坐越后面最弱。看着坐倒数第二排的我欣慰地笑了
【Before 18:00】去小卖部时发现由于我的RP太差,导致小卖部刚到我时机子坏了,又等了十分钟。
【Before 19:00】 回宿舍FB。突然想起今天洛谷打卡是大吉,再发现我被XCD了3次+午饭排队半小时(其实还被几个人插队了 )+小卖店机子坏了(其实还是被大佬插队了 )。
我知道了!由于我今天凶势太大了,所以导致连洛谷都卡BUG显示错误。。。


Evening

【Before 20:00】 众人FB中。。。右上方大佬提出著名格言“我拒(巨)腐”,隔壁大佬PRJ说好趴衣再腐结果还是沉迷腐中。。。后面真·神犇大佬ZYF突然坐在我后面把我吓到了
【23:20】 出艾蕾了!





题解

T1连续自然数和

题目描述
对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。
例子:1998+1999+2000+2001+2002 = 10000,所以从1998到2002的一个自然数段为M=10000的一个解。
注意:单个的一个数不算问题的解。

输入
一个整数M的值(10 <= M <= 2,000,000)。

输出
每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个数按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。

样例输入
10000

样例输出
18 142
297 328
388 412
1998 2002
----------------------------------------------------一条WA的分界线-----------------------------------------------
【难度系数】★☆☆☆☆
【核心算法】暴力枚举
【思路】①设第一项为A1,一共N项,第N项为AN= A1 +N-1,满足以下:
(A1 +AN)N/2=M,即:(2A1 +N-1)N=2M
因N<2*A1 +N-1,所以只要从枚举N到2,从而可以求出A1,当然要判断A1>0,时间复杂度为O( )
用变量
②i枚举开头的数j,从i开始不断加1,直到等于或超过m为止
③在其中用计数器sum不断累加j
④最后判断sum是否等于m,如果是则输出
⑤没有了喵
----------------------------------------------------一条RE的分界线-----------------------------------------------
代码

#include<iostream>
#include<cstdio>
using namespace std;
int m,i,j;
int main(){
   
   
	freopen("combo.in","r",stdin);
	freopen("combo.out","w",stdout);
	cin>>m;
	for (i=1;i<=m/2;i++){
   
   //i枚举开头的数 
		int sum=0;
		for (j=i;j<m;j++){
   
   //j枚举从i开始的每一个数 
			sum+=j;//sum进行累加 
			if (sum>=m) break;
		}
		if (sum==m) cout<<i<<" "<<j<<endl;//打印输出 
	}
}

T2简单游戏

题目描述
Charles和sunny在玩一个简单的游戏。若给出1-n的一个排列A,则将A1、A2相加,A2、A3相加……An-1、An相加,则得到一组n-1个元素的数列B;再将B1、B2相加,B2、B3相加,Bn-2、Bn-1相加,则得到一组n-2个元素的数列……如此往复,最终会得出一个数T。而Charles和sunny玩的游戏便是,Charles给出n和T,sunny在尽可能短的时间内,找到能通过上述操作得到T且字典序最小的1~n的排列。(sunny大声说:“What an easy game!”,接着几下就给出了解),Charles觉得没意思,就想和你玩,当然,你可以用一种叫做“电子计算机”的东西帮你。

输入
本题有多组数据,对于每组数据:一行两个整数n(0<n<=20),t即最后求出来的数。两个0表示输入结束。

输出
对于每组测试数据输出一行n个整数,用空格分开,行尾无多余空格,表示求出来的满足要求的1~n的一个排列。

样例输入
4 16
3 9
0 0

样例输出
3 1 2 4
1 3 2
----------------------------------------------------一条MLE的分界线-----------------------------------------------
【难度系数】★★★☆☆
【核心算法】DFS+剪枝
【思路】①用变量i枚举开头的数
②j从i开始不断加1,直到等于或超过m为止
③在其中用计数器sum不断累加j
④最后判断sum是否等于m,如果是则输出
⑤没有了喵
【思路】题目要求1-N的一个排列A1,A2…An使得C(N-1,0)A1+C(N-1,1)A2+….+C(N-1,N-1)AN=T,
即: -----①式
方法很好确定,先把C(N-1,i)求出来,然后只要把每一个位上的数确定好就可以了,所以采用深度优先搜索的方法。
①方法:直接搜,用DFS(x,y)表示当前将要确定第x个位置上数,已经确定的和为y,把每种情况都搜出来,然后在递归出口的位置判断①式是否成立,不过很可惜,这种方法得不到分;
②剪枝一:加一个小小的优化,就是在确定第X个数时,保证新求出来的y不能大于T,加上这个优化后,可以得40分;
③剪枝二:由于C(N-1,i)=C(N-1,N-1-i),具有对称性,题目又要求最小字典序列,所以在枚举时当x>n div 2 时,要保证a[x]>a[N+1-x],这样程序速度会提高,但是该题还是只能得40分;
④剪枝三:当枚举到第X个数时,剩余的N-X个数,与剩余的N-X个系数一一对应,让大数和大系数相乘,小数和小系数相乘可以得到最大值,让大数和小系数相乘,小数和大系数相乘可以得到最小值,如果剩余的值不在这个范围内,就不要搜下去,这样可以大大优化,拿样例举例来说:
N=4,T=16
⑤当枚举a[1]=1时,剩余16-1
1=15,剩余的未放置的数为2,3,4,剩余的系数为1,3,3,这样最大值为4
3+3
3+21=23,最小值为41+33+23=19,都超过了15,所以第一个数不能选1。
----------------------------------------------------一条WA的分界线-----------------------------------------------
代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

#define N 25

int f[N][<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值