欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-20 08:41:04
...

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

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

写在前面:

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

A-倒水

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

问题分析:

既然不想装无限的水,为啥要放阳台…第一眼看到这个题目,感觉和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

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

问题分析:

这孩子力气真大,这枣树枣子也真多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

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

问题分析:

震惊了,到底是怎么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

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

问题分析:

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


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

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


F-矩阵求和

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


G-字符串哈希

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

问题分析:

这是我写过最凌乱的代码了,为了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-给钱

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

问题分析:

算贪心算法?每次肯定取能够顶值得最大面值的啦,然后剩余得用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-粘土人

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

问题分析:

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


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

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


写在后面:

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

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

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

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

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

相关标签: 比赛回顾