【ZOJ】3785 What day is that day? ——浅谈KMP在ACM竞赛中的暴力打表找规律中的应用
转载请声明出处:http://www.cnblogs.com/kevince/p/3887827.html ——By Kevince
首先声明一下,这里的规律指的是循环,即找到最小循环周期。
这么一说大家心里肯定有数了吧,“不就是next数组性质的应用嘛”,没错,正是如此。
在ACM的比赛中有些时候会遇到一些题目,可以或必须通过找出数据的规律来编写代码,这里我们专门来讨论下 如何运用KMP中next数组的性质 来寻找一个长数组中的最小循环周期。
先来看一道题
ZOJ 3785
What day is that day?
Time Limit: 2 Seconds Memory Limit: 65536 KB
It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days?
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
There is only one line containing one integer N (1 <= N <= 1000000000).
Output
For each test case, output one string indicating the day of week.
Sample Input
2
1
2
Sample Output
Sunday
Thursday
Hint
A week consists of Sunday, Monday, Tuesday, Wednesday, Thursday, Friday and Saturday.
题目的大意是知道今天是周六,让你求 f = 11 + 22 + 33 + ... + NN 这么多天之后是星期几。
也就是求f % 7对于每个输入的N的值。这题在网上一搜题解,都说是打表找规律,当然这题有两种找法,一是对于每个ii % 7 的值都找规律。
这里我们打表可知 前100个值如下所示
1 4 6 4 3 1 0 1 1 4 2 1 6 0 1 2 5 1 5 1 0 1 4 1 4 4 6 0 1 1 3 2 6 1 0 1 2 2 1 2 6 0 1 4 6 4 3 1 0 1 1 4 2 1 6 0 1 2 5 1 5 1 0 1 4 1 4 4 6 0 1 1 3 2 6 1 0 1 2 2 1 2 6 0 1 4 6 4 3 1 0 1 1 4 2 1 6 0 1 2
有一种找规律的方法是当有数字等于第一个数的时候做个标记,再人工判断是否能够构成一个循环。
不可否认的,对于周期较短的一组数字这样找周期并不难,可是如果周期大到数百数千甚至数万时,靠这种方法找周期恐怕是杯水车薪。
当时我就迷茫在了这一长串的数字中不知所措,猛然想起前不久看过的KMP中next数组的性质,当即想到了用KMP求最小重复子串长度的方法,于是脑洞大开……
该性质为:令j=leni-next[i],如果i%j==0且i/j>1,j就是Pi的最小循环节( Pi表示文本串的前i个字符,leni表示该字符串的长度,一般表示为leni = i + 1)
关键代码如下:
/*注:int next[]为next数组,int arr[]为要找规律的数组,len为数组长度*/
next[] = ;
for(int i = , q = ; i < len; i++){
while(q > && arr[i] != arr[q])
q = next[q-];
if (arr[i] == arr[q])
q++;
next[i] = q;
if (q != && (i + ) % (i + - q) == ){
printf("%d\n", i+-q);
break;
}
}
可以求出最小周期为42。
还有一种找规律的方法是直接对 f % 7 的值进行打表找规律,按照上述方法找到的周期为294,下面要做的就很简单了~
AC代码如下:
#include <cstdio>
const char day[][] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
int s[];
int work(int n)
{
int sum = ;
for(int i = ; i <= n; i++){
sum = sum * n;
sum %= ;
}
return sum;
}
void init()
{
s[] = ;
for(int i = ; i <= ; i++){
s[i] = s[i-] + work(i);
s[i] %= ;
}
}
int main()
{
int T;
int n;
init();
scanf("%d", &T);
while(T--){
scanf("%d", &n);
n %= ;
printf("%s\n", day[ s[n]]);
}
return ;
}
---------------------------------------------------------我是分割线--------------------------------------------------------------
自从上次大开脑洞之后,今天又遇到了一道题,POJ 3070。
题目的大意是让你求第n个斐波那契数的后四位是多少,题目的本意考察的是矩阵快速幂,可是暴力打表又有何不可呢?遂打表用KMP查询,找到周期为15000,顺利水过了这题~
嗯,这篇文章只是跟大家分享一下自己偶然发现的KMP在竞赛中一种用法,在有些题目中使用不免有投机取巧之嫌(就像POJ 3070 ╮(╯▽╰)╭),不过不管投机不投机,只要能AC,就是好方法。O(∩_∩)O哈哈~ 开个玩笑,若有不足之处,还请各位指正。
【ZOJ】3785 What day is that day? ——浅谈KMP在ACM竞赛中的暴力打表找规律中的应用的更多相关文章
- 【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律
转自:http://www.cnblogs.com/kevince/p/3887827.html 首先声明一下,这里的规律指的是循环,即找到最小循环周期. 这么一说大家心里肯定有数了吧,“不就是nex ...
- 浅谈Python在信息学竞赛中的运用及Python的基本用法
浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...
- ZOJ 3622 Magic Number 打表找规律
A - Magic Number Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Subm ...
- 浅谈c#的三个高级参数ref out 和Params C#中is与as的区别分析 “登陆”与“登录”有何区别 经典SQL语句大全(绝对的经典)
浅谈c#的三个高级参数ref out 和Params c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和 ...
- zoj 3785 What day is that day? (打表找规律)
题目 思路:比赛的时候有想过找循环节,但是,打表打错了. 后来,看着过了挺多人,就急了, 看了一下别人的时间 耗时都挺长的,就以为不是找规律, 没想到真是找规律,不过,这个题的数据可能挺大的. AC代 ...
- 浅谈Xcode5和Xcode7在系统创建的文件夹和文件中的区别
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 浅谈KMP算法及其next[]数组
KMP算法是众多优秀的模式串匹配算法中较早诞生的一个,也是相对最为人所知的一个. 算法实现简单,运行效率高,时间复杂度为O(n+m)(n和m分别为目标串和模式串的长度) 当字符串长度和字符集大小的比值 ...
- [原创]浅谈JAVA在ACM中的应用
由于java里面有一些东西比c/c++方便(尤其是大数据高精度问题,备受广大ACMer欢迎),所以就可以灵活运用这三种来实现编程,下面是我自己在各种大牛那里总结了一些,同时加上自己平时遇到的一些jav ...
- 浅谈PipelineDB系列一: Stream数据是如何写到Continuous View中的
PipelineDB Version:0.9.7 PostgreSQL Version:9.5.3 PipelineDB的数据处理组件: 从上图来看主要就是pipeline_streams,strea ...
随机推荐
- SignalR在Xamarin Android中的使用
原文:SignalR在Xamarin Android中的使用 ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 ...
- SmartBusinessDevFramework架构设计-3:考虑开源?
掖着藏着,终归不是好的办法.说的跟花一样,究竟里子是什么东西.一个好的被子,里料是羽绒还是棉花还是丝绵还是黑心棉?有时候,真的是看过之后,才能体验其中的奥秘. 这个架构的设计初衷,总体是为了方便.ne ...
- 完全跨站点跨域名单点(SSO)同步登录和注销
先来说说什么是单点登录(SSO).来自百科的介绍:SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主 ...
- Kth Largest Element in an Array 解答
Question Find the kth largest element in an unsorted array. Note that it is the kth largest element ...
- LeeCode(Database)-Employees Earning More Than Their Managers
The Employee table holds all employees including their managers. Every employee has an Id, and there ...
- Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found
Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found 利用Qt Creator编译工程时,出现如题目所示的错误,其中红色部 ...
- Nginx学习之四-Nginx进程同步方式-自旋锁(spinlock)
自旋锁简介 Nginx框架使用了三种消息传递方式:共享内存.套接字.信号. Nginx主要使用了三种同步方式:原子操作.信号量.文件锁. 基于原子操作,nginx实现了一个自旋锁.自旋锁是一种非睡眠锁 ...
- Servlet页面间对象传递的方法
Servlet页面间对象传递的方法 1.request 2.session 3.application 4.cookie 5.其它的
- [Android 4.4.3] 泛泰A860 Omni4.4.3 20140610 RC2.0 三版通刷 by syhost
欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...
- ZendStudio快捷键 注释的快捷键
注:本文省略“通用快捷键”描述,诸如:ctrl+N=新建,ctrl+O=打开,ctrl+C=复制,ctrl+V,ctrl+X……等等几乎所有软件都通用的一组快捷键,而着重介绍zde独有的快捷键,了解并 ...