【比赛回顾】2020广工文远知行杯新生程序设计竞赛(初赛)

【比赛回顾】2020广工文远知行杯新生程序设计竞赛(初赛)

在这里插入图片描述

写在前面:

已经更新完除E和F以外的题解(因为这两道我没有时间做了,以后抽空做完后补充)。可能我的题解并不是最优的,欢迎交流和讨论~

A-倒水

在这里插入图片描述

问题分析:

既然不想装无限的水,为啥要放阳台…第一眼看到这个题目,感觉和19年决赛的 D-城市的税金题型类似,但仔细一看,这道题就太简单了。只要倒掉就清零,这里我们以记录下倒下的那一秒的时间做清零标志。那么每次查看的时候就用现在的时间减去标记的时间就好咯


AC代码:

#include <bits/stdc++.h>
using namespace std;

//用来标记桶为空的时间 默认0秒时全是空的
int a[100001];

int main()
{
	int n,q,t,x;
	int op;
	cin >> n >> q;
	while ( q-- )
	{
		cin >> op >> t >> x;
		if ( op==1 )
		//记录倒掉的时间
			a[x] = t;
		else
			cout << t-a[x] << endl;
	}
	return 0;
}

B-秋夜easy

在这里插入图片描述

问题分析:

这孩子力气真大,这枣树枣子也真多hhh,这两个树我们知道,要想使它们数量一样,就一定要使先A多枣子的那一颗树,使它的枣子变少,不然永远都不可能达成要求。故一开始要先判断那颗树枣子更多 然后A一下它,再判断一下符不符合要求,符合就输出,不符合再重复这个步骤。


AC代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin >> t;
	while ( t-- )
	{
		int a,b;
		cin >> a >> b;
		int ans=0;
		while ( a!=b )
		{
			if ( a>b )
				a /= 2;
			else
				b /= 3;
			ans++;
		}
		cout << ans << endl;
	}
	return 0;
}

C-秋夜hard

在这里插入图片描述

问题分析:

震惊了,到底是怎么A能够使果子变多的!!hhh看到了一条致富之道。emmmm,对比一下上一题,这两个树我们知道,其实没有区别,因为操作方式都是一样的,而不像上一题一棵树/2一棵树/3。再看下题目要求,emmmm x的平方,那不就A出界了么(即超过10000)那A出界了是不能操作还是最多按10000算呢?

说实话当时想这个问题想了很久,但…突然想了想,只要数字大于100取平方就会A出界,那其实就很没用欸,如果取平方这个操作,那这道题的样例就有bug了,因为只要大于100的两个数,分别取平方A,两下就能都爆10000,不就数量相等了么?所以说取平方这个操作只是为了迷糊你的。

然后就是与上一题一样的思路咯~

要想使它们数量一样,就一定要使先A多枣子的那一颗树,使它的枣子变少,不然永远都不可能达成要求。故一开始要先判断那颗树枣子更多 然后A一下它,再判断一下符不符合要求,符合就输出,不符合再重复这个步骤。


AC代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin >> t;
	while ( t-- )
	{
		int a,b;
		cin >> a >> b;
		int ans=0;
		while ( a!=b )
		{
			if ( a>b )
				a = sqrt(a);
			else
				b = sqrt(b);
			ans++;
		}
		cout << ans << endl;
	}
	return 0;
}

D-好人easy

在这里插入图片描述

问题分析:

因为数字比较小,所以直接暴力遍历就能出来,关于判断回文,我采用的是放入数组中,然后对称判断是否符合回文性质,下面我详细注释说明了一下


AC代码:

#include <bits/stdc++.h>
using namespace std;

int a[7];

int main()
{
	int n;
	cin >> n;
	int i,j;
	for ( i=1; i<=n; i++ )
	{
	//小于等于9直接输出
		if ( i<=9 )
			cout << i << endl;
		else
		{
			int temp = i;
			int num=0;
			//计算这是几位数
			while ( temp>0 )
			{
				num++;
				temp /= 10;
			}
			temp = i;
			//从这个数字末位取余依次放入数组中
			//即将这个数字每一位依次拷贝进入数组
			for ( j=num; j>=1; --j )
			{
				a[j] = temp%10;
				temp/=10;
			}
			temp = i;
			int mark=0;
			//只用检验一半就好
			for ( j=1; j<=num/2; ++j )
			{
				if ( a[j] != a[num-j+1] )
				{
					mark = 1;
					//如果不相等直接跳出循环
					//mark=1即不符合条件
					break;
				}					
			}
			if ( mark==0 )
				cout << temp << endl;
		}
	}
	return 0;
}

E-好人hard

在这里插入图片描述


F-矩阵求和

在这里插入图片描述


G-字符串哈希

在这里插入图片描述

问题分析:

这是我写过最凌乱的代码了,为了AC不顾一切hhhh,其实题目并不难理解,但就是题目字太多太绕了。但其实没有什么难度,就是按照要求将文字翻译成代码而已,实际上考验的还是基本功,下面的代码我加了详细的注释


AC代码:

#include <bits/stdc++.h>
using namespace std;

//这个没有严谨的说法
//我只是为了存储后面的特殊情况,找的一个比较后的地址而已 
#define k 1000

int main()
{
	//s存放的是一个个单词
	//其实这个2000我是随便起的
	//但我很怕越界,因为题目有说最大全部字母加起来100000个
	//按照特别奇葩的数据 即一个字母一个单词,最多有100000个单词 
	//一开始我取的是150000,可是太多了,根本运行不了 
	//其实应该取133333是最准确的,因为最多1000000个单词和33333个合并字符串储存空间 
	//我就想取小点,看能不能AC先把,就取2000了 
	char s[2000][254];
	
	// 因为s不能太大,我就专门起了一个s1来临时记录拼接的单词了 
	char s1[2000][254];
	
	//清零 
	memset ( s,0,sizeof(s) );
	memset ( s1,0,sizeof(s1) );
	
	int n;
	cin >> n;
	int i=1,j=1;
	
	//读入数据 
	for ( i=1; i<=n; ++i )
		cin >> s[i];
		
	int times=n/3;
	int index = 1;
	
	//计算次数并逐次输出 
	while ( times-- )
	{
		//每三个单词拼接成一个临时s1 
		for ( i=1; i<=3; ++i )
			strcat(s1[index],s[j++]);
			
		//偷懒直接使用C++自带的反转函数 
		reverse(s1[index],s1[index]+strlen(s1[index]) );
		
		//输出第一个字母 
		cout << s1[index][0]; 
		
		//计算中间的数值有没有超 
		int len=strlen(s1[index]);
		if ( (len-2)>9 )
		{
			//若大于9则计算中间位数的位数 
			int num=0;
			while ( len>0 )
			{
				num++;
				len/=10;
			}
			cout << num;
		}
		else
		//否则就直接输出 
			cout << len-2;
			
		//输出最后一个字母 
		cout << s1[index][strlen(s1[index])-1] << endl;
		
		//下标加一 指向下一个拼接字符串 
		++index;
	}
	
	
	
	
	//有的情况会有余1—2个单词,分别考虑 
	if ( n%3 == 1 )
	{
		strcat(s1[k],s[j]);
		
		//按照题目要救加上 "pmznb"
		strcat(s1[k],"pmznb");
		strcat(s1[k],"pmznb");
		
		//下面的操作和上面的一模一样,其实可以封装成函数,
		//但懒得考虑了hh还是copy来的快一点 
		reverse(s1[k],s1[k]+strlen(s1[k]) );
		cout << s1[k][0]; 
		int len=strlen(s1[k]);
		if ( (len-2)>9 )
		{
			int num=0;
			while ( len>0 )
			{
				num++;
				len/=10;
			}
			cout << num;
		}
		else
			cout << len-2;
		cout << s1[k][strlen(s1[k])-1] << endl;
	}
	
	//下同余1的情况 
	if ( n%3 == 2 )
	{
		strcat(s1[k],s[j++]);
		strcat(s1[k],s[j++]);
		strcat(s1[k],"pmznb");
		reverse(s1[k],s1[k]+strlen(s1[k]) );
		cout << s1[k][0]; 
		int len=strlen(s1[k]);
		if ( (len-2)>9 )
		{
			int num=0;
			while ( len>0 )
			{
				num++;
				len/=10;
			}
			cout << num;
		}
		else
			cout << len-2;
		cout << s1[k][strlen(s1[k])-1] << endl;
	}
	return 0;
}

H-给钱

在这里插入图片描述

问题分析:

算贪心算法?每次肯定取能够顶值得最大面值的啦,然后剩余得用1元补上去,下面同样有详细的注释。


AC代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin >> t;
	while ( t-- )
	{
		int a,b,n,s;
		cin >> a >> b >> n >> s;
		//先计算最少用多少个n可以凑成s
		int times=s/n;
		if ( times<=a )
		{
		//如果小于a,就取times张就好,计算缺值用b能否补齐,能则符合题意
			if ( times*n+b >= s )
				cout << "YES" << endl;
			else
				cout << "NO" << endl;
		}
		else
		{
		//如果大于a,那么就把全部的n砸进去,然后计算这个大缺值能否用b补齐
			if ( a*n+b >= s )
				cout << "YES" << endl;
			else
				cout << "NO" << endl;
		}
	}
	return 0;
}

I-粘土人

在这里插入图片描述

问题分析:

要求要最远,那么就是把手办往两边挪动咯,记得要小心注意顶位的情况,即到达最左和最右不能再移动了。


AC代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n,x,a,b;
	int t;
	int maxmove;
	int temp;
	cin >> t;
	while ( t-- )
	{
		cin >> n >> x >> a >> b;
		//就默认a大把,这样子后面好操作少讨论
		if (a<b)
		{
			temp = a;
			a = b;
			b = temp;
		}
		//计算最多两个手办都移动到最左和最右的步数
		//n-a 和 b-1两者相加即是结果
		maxmove = n-a+b-1;
		//如果大于就直接输出,因为可以不挪完全部操作
		if ( x>=maxmove )
			cout << n-1 << endl;
		else
			cout << a-b+x << endl;	
	}
	return 0;
}

J-dcnb

在这里插入图片描述
题解略


写在后面:

这一次的初赛可能是最简单的了吧,比第一次月赛和第二次月赛相比就小巫见大巫了,直接A爆的大神也是有的,但我还是差两题没时间做出来。

唯一有点新奇的是竟然有四道母子题。

一道是矩阵求和,我估计是一道要找规律的证明题吧,毕竟数据那么大,第二道是好人hard,好人太难了,也是大数据,用easy的方法肯定会超时,要用优化记忆的方法。

在这里插入图片描述

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值