【USACO 2019 December Silver】MooBuzz

心已入冬 提交于 2020-05-02 17:43:13

各位苦闷的父老乡亲们,

如果有问题,然后看到了这篇文章,说明你赚大喽!

如果需要测试自己的题,点这儿

阅读之前,不妨先点个赞呗,我们有个比赛,急!!!

直入主题

题目描述

Farmer John 的奶牛们最近成为了一个简单的数字游戏“FizzBuzz”的狂热玩家。这个游戏的规则很简单:奶牛们站成一圈,依次从一开始报数,每头奶牛在轮到她的时候报一个数。如果一头奶牛将要报的数字是 3 的倍数,她应当报“Fizz”来代替这个数。如果一头奶牛将要报的数字是 5 的倍数,她应当报“Buzz”来代替这个数。如果一头奶牛将要报的数字是 15 的倍数,她应当报“FizzBuzz”来代替这个数。于是这个游戏的开始部分的记录为:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16
由于词汇的匮乏,奶牛们玩的 FizzBuzz 中用“Moo”代替了 Fizz、Buzz、FizzBuzz。于是奶牛版的游戏的开始部分的记录为:
1, 2, Moo, 4, Moo, Moo, 7, 8, Moo, Moo, 11, Moo, 13, 14, Moo, 16
给定 N(1≤N≤10^9),请求出这个游戏中第 N 个被报的数。



输入
输入包含一个整数 N。

输出
输出游戏中被报出的第 N 个数。

样例输入
4

样例输出
7

数据范围限制
测试点 2-5 满足 N≤10^6。
全部测试点满足 N≤10^9(我恨)

提示
第 4 个被报的数是 7。前 4 个被报的数是 1、2、4、7,因为我们在奶牛说“Moo”时就会跳过数字。

这道题这么一看,嘿嘿,直接暴力保分那。

题意理解
题目比较长,USACO好像就爱用很长的题目 ,大体意思就是要求你求出第n个既不是3的倍数也不是5的倍数的数。

思路(咳咳咳,认真听)
我们可以先看一下题目描述中给的样例

1, 2, Moo, 4, Moo, Moo, 7, 8, Moo, Moo, 11, Moo, 13, 14, Moo, 16

我们可以继续续写下去:

1, 2, Moo, 4, Moo, Moo, 7, 8, Moo, Moo, 11, Moo, 13, 14, Moo, 16,17,Moo,19,Moo,Moo,22,23,Moo,Moo,26,Moo,28,29,Moo,31……

(重点注意)

经过枚举,我们发现,1-15与16-30 Moo 的位置一样!

然后我们就可以愉快地做这道题了

直击code!


#include<cstdio>
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<cstdlib>
#include<stack>
#include<ctime>
#include<map>
#include<list>//常用头文件合集,大佬若不嫌弃可以拿去用用
using namespace std;

int main()
{
    int n;
    scanf("%d",&n);
    int tmp1=n%8;//这个代表n是我们发现的规律中的第几个
    int ans=n/8*15;//这个代表n在第几个循环
    int cnt=0;//这个代表第cnt个数(注意,是数,不是Moo)
    for(int i=1; i<=16; i++)
    {
        if(i%3!=0 && i%5!=0) cnt++;
        if(cnt==tmp1)
        {
            printf("%d\n",ans+i);
            return 0;
        }
    }
    return 0;
}

嘿嘿,我想你们的小手已经不自觉的按下了ctrl c,可是这个代码是不对滴,

不信就看看(QwQ)

主要原因是我们没有考虑当n为15倍数时的情况,这种情况下,循环不会执行,所以才不会输出。我们可以把循环改一改,我比较懒,直接加了一个特判。

真正的AC代码

这回信了吧

#include<cstdio>
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<cstdlib>
#include<stack>
#include<ctime>
#include<map>
#include<list>
using namespace std;
#include<cstdio>

int n,cnt,a[10]={14,1,2,4,7,8,11,13};
int main(){
	scanf("%d",&n);
	cnt=n%8;if(n%8!=0) n/=8;else n/=8,n--;
	printf("%d",n*15+a[cnt]);
	return 0;
}

虽然已经有了同样思路,但我觉得我的更详细,而且适合中小学生OIer,谢谢!

既然已经看到这,那就给个赞吧!谢谢!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!