2020年校内ACM排位赛 NO.1场 题解&反思

J总设置的中午12点到傍晚17点的比赛时间,属实让一个每天要睡午觉的菜菜懵逼+难熬啊。途中差点睡着,小错误不断,题目难度也判断失误(预估高了题目难度QAQ,某些题目怎么着也得来点dp、快速幂或者卡数据啥的东东啊)。好了,废话太多了,还是自己定位不够准确导致罚时飙升,不太想继续切题了,突突突…话说这是手速场(大型茶话会)吧…

Problem A:number

Description
300iq loves numbers who are multiple of 300.
One day he got a string consisted of numbers. He wants to know how many substrings in the string are multiples of 300 when considered as decimal integers.
Note that leading and trailing zeros are allowed (both in original string and substrings you chose) and the same substring appearing in different places can be counted multiple times.

Input
A single line consisting a string consisted of characters ‘0’ to ‘9’.
Output
The number of substrings that are multiples of 300 when considered as decimal integers.

Sample Input
600
Sample Output
4

HINT
‘600’, ‘0’, ‘0’, ‘00’ are multiples of 300. (Note that ‘0’ are counted twice because it appeared two times)
let the string in the input be s, 1≤∣s∣≤1e5.

思路:
让求的是300的倍数。可以拆成既是3的倍数也是100的倍数。
找到2个规律:
1.对于3的倍数来说就是各个位上的数值加起来和对3取余答案是0
2.对于100的倍数来说就是要求后两位至少为0
可以发现两个相同余数之间都是算作答案里面的,举个栗子来解释一下这句话:
假设给出的整数是:1 0 1 0 0 1 2 0 0 0
对3取余的结果:1 1 2 2 2 0 2 2 2 2
通过求前缀和得到 “对3取余的结果”,需要了解一下什么叫 “两个相同余数之间”
拿上面的例子,取余结果为2的区间是 1 0 0 1 2 这个区间
后面少3个0是因为,第一次遇到连续的2个0,就是更新答案的地方,必须到这个地方停下来
此时取余为2的个数为4 (2 2 2 0 2,4个2)
这个区间就是下面这个五个答案:001200 01200 1200 00
没有后面两个0 0,是因为单个0我们一开始就需要特殊处理一下
结合代码具体理解:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
char str[N];
typedef long long ll;
ll ans=0, cnt[N];

int main()
{
    scanf("%s",str);
    cnt[0]=1;
    int len=strlen(str);
    for(int i=0; i<len; i++){
        if(str[i]=='0')   ans++;//先处理单个0的情况
    }
    int sum=0;
    for(int i=0; i<len-1; i++){
        sum += str[i]-'0';
        sum%=3;
        if(str[i]=='0' && str[i+1]=='0')   ans+=cnt[sum];
        cnt[sum]++;
    }
    printf("%lld\n",ans);
    return 0;
}

Problem E:马老板的王者荣耀

Description
老板度假归来已经一个月了,他十分的无聊,就向您询问有没有什么解闷的游戏。
“我好无聊啊,你有什么好玩的游戏推荐吗?”
“玩王者荣耀啊!!”
马老板本来是拒绝的,“我马××就是无聊死,从我这300层的别墅跳下去,我也不玩这**游戏!!”
…………
“真好玩!!”
“噫~”,你发出了鄙视的声音。
马老板从此迷上了这款游戏,在马老板日复一日的练习下马老板变得十分 nb。

之后马老板参加了“单挑之王“比赛,并顺利的打到了总决赛。马老板十分想获得“单挑之王“的冠军。于是他将要选用元歌这个单挑十分 nb (纯属瞎扯) 的英雄,但是他并不会这个英雄的连招。他便去网上学习,他一共看了三个教学视频,视频给出的连招顺序分别是:

“1 4 3 3 2 2 3”
“1 3 4 3”
“1 4 3 3 2 2 3”

请您输出常用的(出现次数多的)那套连招。

Input

Output
用的连招顺序,每个数字中间用空格隔开。

Sample Output
1 4 3 3 2 2 3

思路:单纯的输出题…比谁手速快?

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

int main()
{
	else cout<<"1 4 3 3 2 2 3"; 
	return 0;
}

Problem F:马老板的强迫症

Description
在您的帮助下,马老板通过炒股又狠狠的赚取了一大笔,稳固了他本来就不可动摇的全球首富的地位,继续着他的奢靡的生活。

现在马老板厌倦了这种奢靡的生活,他决定开着他的私人飞机去度假。在他度假的过程中,他发现了 n 座山清水秀的小岛。心痒难耐的马老板便想买下这些小岛。但是马老板有严重的强迫症,如果这 n 个小岛不在一条直线上,他就会十分难受。于是他请您帮他计算这 n 个小岛是否在一条直线上。然后马老板再决定是否买这 n 个小岛。

Input
一个整数 n (3 <= n <= 10),代表小岛的个数。
接下来的 n 行,每行输入一个小岛的坐标 x y (-100 <= x, y <= 100)。
Output
如果这些小岛在一条直线上便输出 “Mai!MaiDaKuaiDe”,否则输出 “SuanLeBa”(不包括引号)。

Sample Input
6
1 2
2 3
3 4
4 5
5 6
6 7
Sample Output
Mai!MaiDaKuaiDe

思路:把第一个点拿出来,其他点和他求斜率,看看都相等不相等。没有斜率和斜率为零用两个特判。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,t,x[11],y[11],z=-1,p=-1,q=-2;
double k[11];

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>x[i]>>y[i];
	for(int i=2;i<=n;i++)
		k[i]=((y[i]-y[1])/1.0)/((x[i]-x[1])/1.0);
	
	for(int i=2;i<n;i++)
		if(k[i]!=k[i+1]) z=0;
	
	for(int i=1;i<n;i++) //x同(斜率为0)
    	if(x[i]!=x[i+1]) p=0;
	 for(int i=1;i<n;i++) //y同(没有斜率)
    	if(y[i]!=y[i+1]) q=0;
    	
	if(z==-1||p==-1||q==-2)  cout<<"Mai!MaiDaKuaiDe";
	else  cout<<"SuanLeBa"; 
	return 0;
}

Problem G: C 马老板的股票

Description
马老板是这个星球最富有的人,马老板拥有常人无法想象的财产。
马老板表示他对钱不感兴趣,他只对花钱感兴趣,但是他想看一看他到底能赚多少钱。马老板便买了很多股票,价值 n 万元。马老板的股票有一个奇怪的规律:每 t1 天,股票价值就会翻倍,每 t2 天便会亏损 k 万元(如果当天同时出现翻倍和亏损,则先翻倍后亏损)。懒惰的马老板高薪聘请了您,请帮他计算 m 天后,他的股票价值多少万元。如果您不能准确的计算出结果,马老板便会辞退您!

Input
五个整数 n, t1, t2, k, m (0 < n, k < 100; 2 < t1, t2, m < 30)
Output
一个整数,代表 m 天后股票的价值。

Sample Input
10 2 4 2 4
Sample Output
38

HINT
注意股票价值不应为负。

思路:枚举天数,for i from 1 to n,看 i 是 t1 的倍数还是 t2 的倍数,3个判断 + “股票价值不应为负”对应的特判。

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

int main()
{
	ll n,t1,t2,k,m;
	cin>>n>>t1>>t2>>k>>m;
	ll ansa=n;
	
	for(int i=1; i<=m; i++)
	{
		if(i%t1==0 && i%t2!=0)	ansa=ansa*2;
		if(i%t1!=0 && i%t2==0)	ansa-=k;
		if(i%t1==0 && i%t2==0)	ansa=ansa*2-k;
	}

	if(ansa<=0) cout<<"0"; //注意特判 
	else cout<<ansa;
	return 0;
}

Problem H:马老板的征婚大会

Description
马老板在玩王者荣耀的时候看到了好多情侣,马老板十分羡慕。马老板心想自己打拼那么多年,是时候找个对象了。于是马老板拿出了一顿早饭钱举办了一场征婚大会。马老板对自己对象有三项要求:

  1. 贤惠体贴
  2. 身材要好
  3. 颜值要高

符合这三项中的二项便符合马老板的要求,即有机会成为马老板的对象,从此享受荣华富贵。因此吸引了很多的人来参加。

本次大会有 n 个人报名参加,接下来 n 行,每行输入三个整数 0 或 1;1 代表这一项符合要求、0 代表不符合要求。

马老板日理万机,无暇处理大会事宜,因此将这项任务委托给了您,您只需要告诉马老板有多少人符合马老板的要求即可。

Input
一个整数 n (0 <= n <= 100),代表参加征婚大赛的人数。
接下来 n 行,每行输入三个数 0 或 1,代表这一项是否符合要求。
Output
一个整数,代表符合马老板要求的人数。

Sample Input
3
0 0 1
0 1 1
1 1 1
Sample Output
2

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

int main()
{
	int n,x,sum,ansa=0;
	cin>>n;
	for(int j=1; j<=n; j++)	{
		sum=0;
		for(int i=1; i<=3; i++) {
			cin>>x;
			if(x==1)  sum++;
		}
		if(sum>=2)  ansa++;
	} 
	cout<<ansa;
	return 0;
}

Problem I:马老板的私房钱

Description
马老板在征婚大赛上成功的找到了心仪的对象,并在五年后与之结婚了。
虽然马老板如愿以偿的找到了对象,但是他的财政大权却丢失了。可怜的马老板只能偷偷的藏私房钱了。

马老板为了方便藏私房钱,他把所有的现金换成了 n 块边长为 1 分米的正方体金砖。他想把金砖藏到 10 公里外的一个秘密仓库中的 “正方体” 保险箱里。因为定制保险箱太麻烦了,懒惰的马老板不会去定制保险箱,只会用自己有的保险箱装金砖。马老板早就预料到了这一天,因此他提前买了非常非常多的保险箱。已知马老板所有的保险箱都是边长为 k (k = 1, 2, 3, 4, 5…) 分米的正方体。马老板虽然有钱但是他并不擅长数学,所以他向您请教他最少需要多少个保险箱才能 “正好装下所有金砖” ,即用到的每一个保险箱都正好装满金砖。

Input
一个整数 n (1 <= n <= 100),代表金砖的个数。
Output
一个整数,代表最少需要的保险箱的个数。

Sample Input
70
Sample Output
4

HINT
关于样例,您应该选择边长为 2、3 的保险箱各 2 个。如果是选择一个边长为 4 的箱子,则还需要 6 个边长为 1 的箱子,这样就不是最少了,马老板让您不用担心保险箱够不够,因为他的保险箱非常多~

思路:一开始还以为是dp,结构直接暴力枚举就可以。因为数据只有100,正方体边长最大为4,边长为1最多能选100个,边长为2最多能选12个,然后四重循环,选最小的。

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

int main()
{
	int n,ansa=1e9;
	cin>>n;
	
	for(int i=0;i<=100;i++)
		for(int j=0;j<=12;j++)
			for(int k=0;k<=3;k++)
			{
				for(int p=0;p<=1;p++)
				    if(i+8*j+27*k+64*p==n)    ansa=min(ansa,i+j+k+p);
			}
	
	cout<<ansa;
	return 0;
}

Problem J:马老板的神奇魔法

Description
马老板刚学会了一种神奇的魔法,于是他便去向马老板娘炫耀他刚学会的魔法。
“你在心中想一个三位数,用 abc 表示 (100 < abc < 999) 并且 a b c 各不相同,规定 key = max(abc, cba) - min(abc, cba),你告诉我 key 的个位上的数,我就知道 key 是多大”

马老板娘当然不相信他的话,于是就在心中想了一个三位数 123,于是得到了 key = 321 - 123 = 198 ,他便告诉了马老板:个位上的数为 8;马老板略加思考后便知道了 key 为 198,马老板娘感到非常的不可思议。
您知道马老板怎么做到的吗?

Input
key 的个位数字 n (1 <= n <= 9)。
Output
一个整数,表示 key 的值。

Sample Input
8
Sample Output
198

思路:无论是abc,还是cba,十位的b是一样的,用大的减去小的。假设 abc 比 cba大,那么意味着 a>c, c-a 肯定借位,b会减小,b-b 就不够了,只能借位,所以十位肯定是9。因为a>c,就算百位上被借了一位,a也至少和c相等,所以百位>=0(百位为0的时候就是一个特判了)。给出的 n 是个位,找找个规律,会发现个位和百位的数字之和为9,因此百位上的数字为 9-n。【一开始还以为是要转化成其他进制去考虑问题…原来duck不必】

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

int main()
{
	int n;
	cin>>n;
	if(n==9)  cout<<"99"; //个位为9时,百位为0
	else  cout<<9-n<<"9"<<n;
	return 0;
}

Problem K:马老板的宠物猪

Description
马老板和马老板娘一起养了一只宠物猪佩奇,佩奇对食物十分挑剔:

  • 周一周四周天 吃鲍鱼
  • 周二周六 吃澳洲龙虾
  • 周三周五 吃燕窝
  • 周八杀猪吃肉

马老板家中鲍鱼,澳洲龙虾,燕窝的数量分别还能供佩奇吃 a, b, c 天。我们都知道,马老板非常懒,所以不到最后一天他是不会去买食物的。于是马老板向您询问,这些食物最多还可以供佩奇吃多少天(从一周中的任意一天开始计算都可以)。
因为从300层的别墅楼顶开直升飞机去买食物真的太麻烦了~

Input
三个整数 a b c (1 <= a, b, c <= 700 000)
Output
一个整数,代表最多的天数。

Sample Input
2 1 1
Sample Output
4

思路:枚举周一到周日,每一次二重循环中求出天数 t,更新成最大的 t 输出。

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

int main()
{
	int a,b,c,minn=0,t;
	cin>>a>>b>>c;
	
	for(int j=1; j<=7; j++)
	{
	    int a1=a,b1=b,c1=c;
	    t=0;
	    for(int k=j;k;k++)
	    {
		    int i=k%7;
		    if(i==1||i==4||i==0) {
			    if(a1!=0)  {a1--; t++;}
			    else break;
		    } 
		    if(i==2||i==6) {
			    if(b1!=0)  {b1--; t++;}
			    else break;
		    } 
		    if(i==3||i==5) {
			    if(c1!=0)  {c1--; t++;}
			    else break;
		    } 
	    }
	    if(t>=minn)  minn=t; 
	}
	cout<<minn;
	return 0;     
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值