关于广西大学20级第一次段考的题解和牢骚

##关于广西大学20级第一次段考的题解和牢骚

前文牢骚

首先要明确,题目不难,甚至可以说是简单,六题除了卡格式和卡时长没有很大的问题。最大的问题是之前的题目出的太简单或者太难,导致中等题做的太少,程序优化次数太少,超时和卡格式现象频出。数据太弱,伪代码都能轻易过关。
其次,在比赛前晚上模题我也感觉难度上略高,但在卡了我们数据的前提下也伪ak了(指有一题数据有问题就没模过)。 
最后吧,希望大家认真学习好代码,有自己的一技之长,最好能有一个自己感兴趣的项目(比如算法,比如前端,比如后端,比如数据处理,比如视图,比如游戏),这一切都基于,你的代码是好的,而不只是对的。

正文部分,题解

题一:打印菱形

题意:给你一个方程,让你去模拟一个图像。如果这题放在比赛,五分钟第一个ac不是问题。
现在来讲一下比较有效的思路,第一是在草稿纸上建立坐标系,把这些点画在坐标系里面,思考这个方程函数如何和坐标系联系在一起,如果可以,你会用怎样的办法去建立这个函数。
第二种可能可行的思路,暴力打印,用if语句判定这个点是否落在了一个区间,如果是,那就打印。这个区间就是总长/2-该行的点数,总长/2+该行打印的点数。
很多同学群里提问吧,我个人理解是之前做的题目没有遇到过太多根据题意模拟的题,单纯是打印了一个自己想当然的菱形(这个lcx可能全责),但是永远要明白,只有根据题意模拟的题才是有灵魂的,纯看样例的模拟会出大问题。
代码中没有注释会难以消化所以建议自己先写。

long long sum = 2 + b * (a - 1);//long long 长整型(防爆破)
	for (long long  i = 1;i <= a;i++) {
			for (long long j = 1;j <= sum;j++) {
				if (j <= sum / 2 - b * (i - 1) / 2 - 1) printf(" ");
				else if (j > sum / 2 - b * (i - 1) / 2 - 1 && j <= sum / 2 + b * (i - 1) / 2 + 1) printf("*");
			}
			printf("\n");
		}
		for (long long i = a;i >= 1;i--) {
			for (long long j = 1;j <= sum;j++) {
				if (j <= sum / 2 - b * (i - 1) / 2 - 1) printf(" ");
				else if (j > sum / 2 - b * (i - 1) / 2 - 1 && j <= sum / 2 + b * (i - 1) / 2 + 1) printf("*");
			}
			printf("\n");//每次都是这种问题
			
		}`

题二:签到题

题意,给你一个数字,判定他是否被9996整除,如果是,打印,如果不是,继续判定,是否被49整除,如果是,打印,如果不是,输出不是的打印。
这题难可能在输出格式上??我估计很多人之前没有接触过这样的打印规则,所以全死了。也可能以前做题太少,或者随手抄抄别人代码就过了,就没管过输出格式。

if (n % 9996 == 0)printf("SurplusYYDS\n");
		else if (n % 49 == 0)printf("????\n");
		else printf("AWSL\n");

代码也无所谓的,这题确实有手就行。

题三:小小数论题

给你一个函数,找出1-99整数中最接近零的函数值。
巧妙运用double ,fabs,pow基本都能过,关键在于你这些函数会不会背。
同样也是有人问我这个很有意思的问题,用选择排序把一百种情况理论上排序出来(细想可能不会爆,但是非常费时间)
我个人理解的最好思路是直接用两个变量ans和p,前者存最小的数据,后者存最小数据的下标。通过比大小来判定这个数据是否是最小数据,并将这个最小数据的下标存入p中
(仔细想来我的思路已经有点动态规划的意思了)

for (int i = 1;i < 100;i++) {
			if (ans > fabs(n * pow(i, 3) + m * i - x)) {
				ans = fabs(n * pow(i, 3) + m * i - x);
				p = i;
			}
		}

题四:辗转相减法

辗转相除的弟弟,不过和小模拟结合原以为会卡掉一片,没想到大多数人都还是明白了题意去模拟,说明模拟不难,难的是思路。这就和第一题形成了鲜明的对比了。
这题我讲一下我理解的优化点,可以用while(n!=m)判定,这样只需要考虑m>n和m<n两种请况。也就能用六行代码解决问题。

while (n != m) {
			if (n > m) {
				printf("%lld-%lld=%lld\n", n, m, n - m);
				n -= m;
			}
			if (n < m) {
				printf("%lld-%lld=%lld\n", m, n, m - n);
				m -= n;
			}
		}

题五:第二大数字

这题cm感觉背锅,数据造的有点大

首先题面没有想卡你们的意思,这题确实再高两个数量级也能过。但是如果是我做这题,我肯定不会想到排序,而是用搜索。排序是什么,是把一堆无序的东西变有序,搜索是查找你需要的东西。那么这题就很简单了。什么是你要的呢,你要第二大的数字,那么你怎么知道他是第二大呢?
我们可以理解一下,当我们知道了最大的那个数字,是不是理所当然把那个最大值剔除了就是第二大了呢?那么下次问你找第三大,第四大,是不是原理就很显然了呢?
但其实我们还可以更加高效的去思考,我们一遍一遍找最大值,第二大值,第三大值,为什么不一次就找齐呢?
其实这是我觉得最有意思的一题,因为集训队刚开始很多c++选手的思路都是sort一下就完事了,但我觉得这题的复杂度没必要用sort,反而是on。
听完我吹逼就讲正事,我们可以在输入每一个数的时候比较大小,然后把最大的数字存到max里,但是这时候max原本的数字就变成了第二大的数字,就给了max2;如果有一个数他比max小但是比max2大,那就很显然了啊,他就是我们想的第二大的值。

while (n--) {
			scanf("%lld", &m);
			if (p < m) {
				ans = p;
				p = m;

			}
			else if (ans < m) {
				ans = m;
			}
		}
		printf("%lld\n", ans);

题六:字符串输出

有朋友问我,这些题目是不是都要用数组存才能做?我和他这么说,理论上,没有一题必须用数组,但我个人习惯上最后一题还是用了数组做。
先讲一下不用数组的思路,查找c 是否出现,没出现则打印出来,出现了就存进一个新变量里来防止自己忘记。接下来再输入一个数,看看这个数是不是m,如果不是,那就回头把c打印出来,如果是,那就两个都可以清空了,直接自觉地的打印lyf。以此类推。
再讲用数组的思路,先存再查,查了之后不打印,直到出现了cm再打印,并且把lyf打印进去。不过这个思路缺点是最后还要把多余的数组都打印出来,就会麻烦一点。我不讲究,不是字符串选手,有个思路就可,不至于手足无措。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
char a[200005];
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
	    long long  n,m;
		long long  ans;
		long long  p;	
		p = 1;
		int flag = 0;
		scanf("%lld\n", &n);
		for (long long  i = 1;i <= n;i++) {
			scanf("%c\n", &a[i]);
			
			 if (a[i-1]=='c' && a[i] == 'm') {
				for (long long  j = p;j <= i - 2;j++) {
					printf("%c", a[j]);

				 }
				printf("lyf");
				p = i + 1;
			}
	    }
		for (long long  i = p;i <= n;i++) {
			printf("%c", a[i]);
		}
		printf("\n");

	}
	return 0;
}

给看到最后一题的同学一些奖励,最后一题直接上完整代码,虽然这是写的最垃圾的一题哈哈。很多前面的变量都延用方便快速k题。

总结

给看到这里的小朋友一点奖励,讲一些我半小时a题的心得,也算是集训队第二次比赛总结出来的经验。
打代码首先要自己看得懂,要用一些自己最常用的名字命名,要看个人习惯,有的人打字快而且丢三落四,建议多打几个字母告诉自己这个叫什么。像我这种记不住人名的人就喜欢用abcd(友人A),而且基本上都是同一套东西,n就是循环次数,t就是几个样本。变量abc,数组xy巴拉巴拉。
 然后就是头文件的打印,每一题的头文件都是重复的,还不如直接复制粘贴一下,自己存一个板子在电脑里,然后做题的时候复制粘贴一下
其他比如说板子,很多人问我板子是什么,板子其实就是你做题一些封装的函数,比如说gcd(辗转相除法),比如说sort(快速排序),还有像冒泡排序,选择排序,甚至质数筛,质数筛打表(做一张已经打好的质数筛表封装在一个数组里)。这些常用的东西你虽然打多会增加熟练度提高你的码量,甚至可以让你成为首a人(第一个做出那题的人),但我觉得大可不必,真正到了生活中,封装的板子不仅能减少你的记忆量,甚至能给你脑子腾出更多的空间去存储其他算法(你可以理解为大脑作为指针存了地址,指向了书本上的内容)。
而优秀的代码往往是这样封装好的代码盒子,你吃透了这些代码盒子能变得更强,但前提是你有足够的时间去学习其他代码盒子。毕竟代码长路漫漫,不是只有算法是核心。

再讲一点有用的废话,while(t–)代替for(int i=1;i<=t;i++)前者是倒叙,后者是升序,这样的语句又清晰又不容易错,关键在于理解计算机的语法,所以学习语言先学习语法,再学习函数,这是亘古不变的。

while(t--)//从t=你输入的值,到t=1,当t=0时跳出循环(先执行循环)
for(int i=1;i<=t;i++)//此时i从1到t,i最后的结果会被自动清空,因为你的定义有且只在这个for循环语句内。(int规定的)

其他看我的代码大家自己吸收,对于大多数巨佬来说可能只是图一乐,但是更多的蒟蒻需要像我这样勇敢的人献出代码来变得更好。
以后如果有时间,我会陆续更新一些oj上大家能做的题解,来为大家变强贡献绵薄之力,毕竟所有有用的oj都有题解,我们这里因为成立时间太短而难以找到,这种事情得有人做,才会有更多的人做。

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1. 什么是Git?它有什么优点? Git是一款版本控制系统,它可以记录代码的历史变化,便于多人协作开发和管理代码。它的优点包括: - 分布式管理:每个开发者都可以拥有一份完整的代码仓库,不需要依赖中央服务器。 - 强大的分支和合并功能:可以轻松地创建和合并分支,便于团队协作和版本管理。 - 快速轻便:Git采用了一些高效的算法和数据结构,使得它的速度非常快。 - 安全性高:Git使用SHA-1算法来保证代码的完整性和安全性。 2. Git的三个区域分别是什么? Git的三个区域分别是工作区、暂存区和版本库。 - 工作区:保存了实际的文件,也就是我们编辑的文件。 - 暂存区:保存了即将提交到版本库的文件,也就是我们通过`git add`命令添加的文件。 - 版本库:保存了所有的提交历史和代码版本,也就是我们通过`git commit`命令提交到Git的代码仓库。 3. 如何创建一个新的分支并切换到这个分支? 可以使用`git branch`命令创建新分支,然后使用`git checkout`命令切换到新分支: ``` $ git branch new_branch # 创建新分支 $ git checkout new_branch # 切换到新分支 ``` 也可以使用`git checkout`命令的`-b`选项,一步完成创建和切换: ``` $ git checkout -b new_branch # 创建新分支并切换到新分支 ``` 4. 如何合并两个分支? 可以使用`git merge`命令合并两个分支: ``` $ git checkout master # 切换到要合并的分支(通常是主分支) $ git merge feature_branch # 合并另一个分支 ``` 在合并过程中,Git会自动检测两个分支的差异,并尝试自动合并代码。如果合并过程中发生冲突,需要手动解决冲突,然后再次执行`git merge`命令。 5. 如何撤销上一次提交? 可以使用`git revert`命令撤销上一次提交: ``` $ git revert HEAD # 撤销上一次提交 ``` 这会创建一个新的提交,用于撤销上一次提交的变更。如果需要撤销多个提交,可以使用`git revert`命令的`-n`选项,指定要撤销的提交数量。 6. 如何回退到某个提交? 可以使用`git reset`命令回退到某个提交: ``` $ git reset --hard commit_id # 回退到指定的提交 ``` 这会将当前分支回退到指定的提交,并重写工作区和暂存区的内容。这会丢失当前提交之后的所有提交记录,谨慎使用。 7. 如何查看提交历史? 可以使用`git log`命令查看提交历史: ``` $ git log # 查看提交历史 ``` 这会列出所有提交的记录,包括提交的哈希值、作者、时间、提交消息等信息。可以使用`--pretty`选项指定输出格式。 8. 如何查看文件的差异? 可以使用`git diff`命令查看文件的差异: ``` $ git diff file_path # 查看工作区与当前版本库的差异 $ git diff commit_a..commit_b file_path # 查看两个提交之间的差异 ``` 这会输出文件的变更内容,包括添加、修改、删除等操作。如果需要查看某个文件的历史变更记录,可以使用`git log`命令的`--follow`选项。 9. 如何从远程仓库拉取代码? 可以使用`git pull`命令从远程仓库拉取代码: ``` $ git pull origin master # 从远程仓库的主分支拉取代码 ``` 这会将远程仓库的代码拉取到本地,并自动合并到当前分支。如果需要从其他分支拉取代码,可以修改`origin master`为相应的分支名称。 10. 如何推送代码到远程仓库? 可以使用`git push`命令将代码推送到远程仓库: ``` $ git push origin master # 将代码推送到远程仓库的主分支 ``` 这会将当前分支的代码推送到远程仓库,并更新远程仓库的代码。如果需要推送到其他分支,可以修改`origin master`为相应的分支名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值