转自:http://www.cnblogs.com/kevince/p/3887827.html

首先声明一下,这里的规律指的是循环,即找到最小循环周期。

这么一说大家心里肯定有数了吧,“不就是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)

还有一种找规律的方法是直接对 f % 7 的值进行打表找规律,按照上述方法找到的周期为294,下面要做的就很简单了~

 #include <iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 605
#define M 200
#define ll long long
using namespace std;
int i,j;
int T;
int l;
int a[N],sum[N];
char s[N];
int next[N];
int fun(int n)
{
int re = ;
for(int i=;i<=n;i++){
re*=n;
re%=;
}
return re;
}
void ini()
{
a[]=sum[]=;
a[]=sum[]=;
s[]='';
s[]='';
for(i=;i<=N-;i++){
a[i]=fun(i);
sum[i]+=a[i]+sum[i-];
sum[i]%=;
s[i]=sum[i]+'';
}
s[i]='\n';
//printf("%s\n",s);
// for(i=1;i<=M;i++){
// printf(" %d %d %d\n",i,a[i],sum[i]);
// printf(" %d",sum[i]);
//}
return;
} void ini2()
{
int j = -, i = ;
next[] = -;
while(i < N-)
{
if(j == - || s[i] == s[j])
{ i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
} void ini3()
{
for(int i = ; i <= N-; ++i)
{
int length = i - next[i]; //循环节的长度
if(i != length && i % length == ) //如果有多个循环
{
printf("%d %d\n", i, i / length);
break;
} }
} int main()
{
int x;
int ans;
ini();
//ini2();
// ini3();
//freopen("data.txt","r",stdin);
scanf("%d",&T);
//while(scanf("%d",&n)!=EOF)
while(T--)
{
scanf("%d",&x);
ans=sum[x%];
if(ans==) printf("Saturday\n");
else if(ans==) printf("Sunday\n");
else if(ans==) printf("Monday\n");
else if(ans==) printf("Tuesday\n");
else if(ans==) printf("Wednesday\n");
else if(ans==) printf("Thursday\n");
else if(ans==) printf("Friday\n");
}
return ;
}

后来又练了一次,用了map

4172110 2016-03-15 15:26:39 Accepted 3785 C++ 820 280 njczy2010
 #include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string> using namespace std; #define N 1005
#define ll long long
#define mod 7 int TT;
int n;
int s[N];
int next[N];
map<int,string> mp; void get_next()
{
int i,j;
i = ;
j = -;
next[] = -;
while(i<N)
{
if(j == - || s[i] == s[j]){
i++;j++;next[i] = j;
}
else{
j = next[j];
}
}
} int quickpow(int x,int n)
{
int re = ;
while(n)
{
if(n&){
re = (re * x) % mod;
}
n /= ;
x = (x * x) % mod;
}
return re;
} void fi()
{
int i;
for(i = ;i < N;i++){
int length = i - next[i]; //循环节的长度
if(i != length && i % length == ) //如果有多个循环
{
printf("%d %d %d\n", i, length, i / length);
break;
}
}
} void ini()
{
int i;
s[] = ;
for(i = ;i < N;i++){
s[i] = (s[i - ] + quickpow(i,i) )%mod;
}
mp[] = "Saturday";
mp[] = "Sunday";
mp[] = "Monday";
mp[] = "Tuesday";
mp[] = "Wednesday";
mp[] = "Thursday";
mp[] = "Friday";
//get_next();
//fi();
//
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ini();
scanf("%d",&TT);
while(TT--){
//while(scanf("%d",&n)!=EOF){
scanf("%d",&n);
cout << mp[ s[ n% ] ] << endl;
}
return ;
}

【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律的更多相关文章

  1. 【ZOJ】3785 What day is that day? ——浅谈KMP在ACM竞赛中的暴力打表找规律中的应用

    转载请声明出处:http://www.cnblogs.com/kevince/p/3887827.html    ——By Kevince 首先声明一下,这里的规律指的是循环,即找到最小循环周期. 这 ...

  2. ZOJ 3622 Magic Number 打表找规律

    A - Magic Number Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Subm ...

  3. zoj 3785 What day is that day? (打表找规律)

    题目 思路:比赛的时候有想过找循环节,但是,打表打错了. 后来,看着过了挺多人,就急了, 看了一下别人的时间 耗时都挺长的,就以为不是找规律, 没想到真是找规律,不过,这个题的数据可能挺大的. AC代 ...

  4. zoj 3629 Treasure Hunt IV 打表找规律

    H - Treasure Hunt IV Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu ...

  5. 【ARC077F】SS kmp+打表找规律

    Description ​ 如果某个串可以由两个一样的串前后连接得到,我们就称之为"偶串".比如说"xyzxyz"和"aaaaaa"是偶串, ...

  6. ZOJ 3785 What day is that day?(今天是星期几?)

    Description 题目描述 It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days? 今天是星期六,11 + ...

  7. ZOJ 3587 Marlon&#39;s String 扩展KMP

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3587 题意:给出两个字符串S和T.S,T<=100000.拿出 ...

  8. zoj 3785 What day is that day?

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5272 打表找规律. #include <cstdio> #incl ...

  9. ZOJ 3785 What day is that day?(数论:费马小定理)

    What day is that day? Time Limit: 2 Seconds      Memory Limit: 65536 KB It's Saturday today, what da ...

随机推荐

  1. 解决IIS的Server Application Error

    问题描述一下: Server Application ErrorThe server has encountered an error while loading an application dur ...

  2. C#中的String.Format方法

    定义String.Format是将指定的String类型的数据中的每个格式项替换为相应对象的值的文本等效项.(1)string p1="xiaomeng";string p2=&q ...

  3. BZOJ4444 SCOI2015国旗计划(贪心+倍增)

    链上问题是一个经典的贪心.于是考虑破环成链,将链倍长.求出每个线段右边能作为后继的最远线段,然后倍增即可. #include<iostream> #include<cstdio> ...

  4. [NOI.AC省选模拟赛3.23] 染色 [点分治+BFS序]

    题面 传送门 重要思想 真的是没想到,我很久以来一直以为总会有应用的$BFS$序,最终居然是以这种方式出现在题目中 笔记:$BFS$序可以用来处理限制点对距离的题目(综合点分树使用) 思路 本题中首先 ...

  5. uva10884 Persephone

    题目戳这里. 找规律. 每一列占据的格子一定是一段区间: 相邻列之间的区间有交. 上界先增后减,下界先减后增. \(f_{i,j,k,0/1,0/1}\)表示考虑前\(i\)列,第\(i\)列,上界为 ...

  6. 莫比乌斯反演题表II

    bzoj3994:[SDOI2015]约数个数和 **很好推+有个小结论bzoj3309:DZY Loves Math ***很好推+线筛某函数/卡常bzoj4816:[Sdoi2017]数字表格 * ...

  7. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  8. HNOI2002 营业额统计 [Splay]

    题目描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是 ...

  9. Codeforces Round #526 (Div. 2) A.B

    A. The Fair Nut and Elevator 题目链接:https://codeforces.com/contest/1084/problem/A 题意: 一栋房子有n层楼,同时有个电梯( ...

  10. URAL - 1486 Equal Squares 二维哈希+二分

    During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued about who o ...