NOIP2005普及组第4题 循环

  

时间限制: 1 Sec  内存限制: 128 MB
提交: 27  解决: 6
[提交][状态][讨论版][命题人:外部导入]

题目描述

乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。

众所周知,2的正整数次幂最后一位数总是不断的在重复2,4,8,6,2,4,8,6……我们说2的正整数次幂最后一位的循环长度是4(实际上4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:

循环

循环长度

数字 循环 循环长度
2 2、4、8、6 4
3 3、9、7、1 4
4 4、6 2
5 5 1
6 6 1
7 7、9、3、1 4
8 8、4、2、6 4
9 9、1 2

这时乐乐的问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数n的正整数次幂来说,它的后k位是否会发生循环?如果循环的话,循环长度是多少呢?

注意:

1. 如果n的某个正整数次幂的位数不足k,那么不足的高位看做是0。

2. 如果循环长度是L,那么说明对于任意的正整数a,n的a次幂和a + L次幂的最后k位都相同。

输入

只有一行,包含两个整数n(1 <= n < 10100)和k(1 <= k <= 100),n和k之间用一个空格隔开,表示要求n的正整数次幂的最后k位的循环长度。

输出

包括一行,这一行只包含一个整数,表示循环长度。如果循环不存在,输出-1。

【数据规模】

对于30%的数据,k <= 4;

对于全部的数据,k <= 100。

样例输入

32 2

样例输出

4

提示

题目类型:高精度乘法+规律。

分析:一般来说遇到这种问题,像10^100这样的数据范围,不是高精度就是另有规律可循。这是一个循环结问题,以往有遇到打表找规律的这种问题,极容易被忽悠。

WA点:

  1. 答案有可能存在long long int保存不下的情况,需要用数组保存。并且过程需要高精度高乘。
  2. 既需要高精度低乘,又需要高精度高乘,在数组拷贝的过程中极可能出现失误。
  3. 单组输入

TLE点:

  1. 在数组的比较过程中,可以用O(1)的时间复杂度解决,而不必O(100)。

高精度高乘:大数与大数相乘,数组乘数组实现。

高精度低乘:大数与整数(较小)相乘,数字乘数字实现。

规律:当后K为数字存在循环结的必要条件是,后K-1位数字存在循环结,并且K的最小循环结必定是K-1的最小循环结的整数倍。并且对于当前位数的处理不必要取模,既然已经用了数组高精度保存便可以只考虑当前位数。在比较时,显然后K-1位已经按照之前的循环结递推过来必定相同,我们只需要比较倒数第K位是否相等即可。

技巧:关于查找循环结上限的问题,当前位数出现可能是0,1,2,3,4,5,6,7,8,9,在10次之内必定会出现与第一次相同的情况,当前次数*K-1的循环结即可得到K的循环结。如果10之内未能出现,那肯定就不存在了。

解析:我直接举一个例子进行说明吧:111 3(由于1的循环长度就是1,所以我直接从末两位循环开始)

我们来看111的末两位循环:

111  -> 321 -> 631 -> 041 -> 551 -> 161 -> 871 -> 681 -> 591 -> 601 -> 711

711处末两位出现循环,循环长度为10,循环节为11-> ...-> 01

现在我们再来看末三位循环:

111->...->601 (10个数)

711->...->201 (201就是601^2的末三位)

311->...->801 (801就是601^3的末三位)

911->...->401 (401就是601^4的末三位)

511->...->001 (001就是601^5的末三位)

111->...->601 (601就是601^6的末三位)

末三位的循环长度就是5*10=50;

好了,现在来讲具体的做法,并假设我们现在求数字n的后k位循环。

朴素的做法就是直接求n^2,n^3,n^4.。。。,并判断是否出现循环。但观察上面的演示例子,我们发现可以不必这样,以n=111为例,末两位循环节长度为10,即表示n与(n^10)*n的末两位是相同的。对于末三位的循环,肯定是(m*n^10),即m*(n^10)与n^10的末三位是相同的,m*(n^10)*n的末三位与n相同。 于是,计算末三位循环的时候,我们就直接将n^10作为第一个数,然后每次乘n^10,共乘5次,末三位出现循环,即m=5,所以末三位循环街长度就为5*10=50。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
string s;
int m, k; int i, j; int a[], aans[], n[], ans[], last[], now[], t[];
int single_j[] = { ,,,,,,,,, };//单循环结
void init()
{
memset(a, , sizeof a); memset(last, , sizeof last);
memset(aans, , sizeof aans); memset(now, , sizeof now);
memset(ans, , sizeof ans); memset(n, , sizeof n); memset(t, , sizeof t);
//for (int i = 1;; i++) { if (m == 0) break; n[i] = m % 10; m /= 10; }//将m存入数组n,以便于高精度
}
void multiplyh(int x[], int y[], int z[])
{//高精度高乘
int up = ;
for (int ii = ; ii <= k; ii++)
{
for (j = ; j <= k; j++)
{
z[ii + j - ] += (x[j] * y[ii] + up) % ;
up = (x[j] * y[ii] + up) / ;
}
up = ;
}
for (int ii = ; ii <= k; ii++) {//进位
z[ii + ] += z[ii] / ;
z[ii] %= ;
}
}
void multiplyl(int x[], int yy, int z[])
{//高精度低乘
int up = ;
for (int ii = ; ii <= k; ii++)
{
z[ii] = (x[ii] * yy + up) % ;
up = (x[ii] * yy + up) / ;
}
}
int main()
{
//scanf("%d%d", &m, &k);
init();
cin >> s;
cin >> k;
int temp = , len = s.size();
for (i = len - ; i >= len - k; i--)
n[++temp] = s[i] - '';
int tmp = ;
for (int i = ; i <= k; i++) ans[i] = n[i];
for (int i = ; i < single_j[n[]]; i++)
{
memset(aans, , sizeof aans);
multiplyh(ans, n, aans);
for (int j = ; j <= k; j++) { ans[j] = aans[j]; }//更新为第一次出现末尾循环节的状态
}
t[] = single_j[n[]];//最低位的循环结
for (int i = ; i <= k; i++) now[i] = ans[i];
int pos = ;//当前倒数位数
while (pos <= k)
{
for (int j = ; j <= k; j++)
{
ans[j] = n[j];
last[j] = now[j];
}
tmp = ;
while (tmp < )
{
tmp++;
memset(aans, , sizeof aans);
multiplyh(ans, now, aans);
for (j = ; j <= k; j++)
{
ans[j] = aans[j];
}
if (ans[pos] == n[pos]) break;//找到循环结
memset(aans, , sizeof(aans));
multiplyh(last, now, aans);//更新last
for (j = ; j <= k; j++) last[j] = aans[j];
}
if (tmp >= ) { cout << -; return ; }
for (int j = ; j <= k; j++) now[j] = last[j];
memset(aans, , sizeof aans);
multiplyl(t, tmp, aans);//更新循环节数组
for (int i = ; i <= ; i++) t[i] = aans[i];
pos++;
}
int flag = ;//不输出前导0
for (int i = ; i >= ; i--)
{
if (t[i]) flag = ;
if (flag) cout << t[i];
}
return ;
}

NOIP2005普及组第4题 循环的更多相关文章

  1. NOIP2005普及组第3题 采药 (背包问题)

    NOIP2005普及组第3题 采药 时间限制: 1 Sec  内存限制: 128 MB提交: 50  解决: 23[提交][状态][讨论版][命题人:外部导入] 题目描述 辰辰是个天资聪颖的孩子,他的 ...

  2. 【动态规划】Vijos P1104 采药(NOIP2005普及组第三题)

    题目链接: https://vijos.org/p/1104 题目大意: T时间,n个物品,每个耗时ti,可获得收益ci,求最大收益. 题目思路: [动态规划] 01背包裸题.一维二维都过了,放个一维 ...

  3. [NOIP2005] 普及组 循环

    陶陶摘苹果 校门外的树 采药 以上三道都不是重点 循环 题目描述 乐乐是一个聪明而又勤奋好学的孩子.他总喜欢探求事物的规律.一天,他突然对数的正整数次幂产生了兴趣. 众所周知,2的正整数次幂最后一位数 ...

  4. NOIP2015普及组第四题推销员

    好久没有写博客了,今天再写一篇.还是先看题: 试题描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家 ...

  5. NOIP2008普及组第3题 传球游戏

    NOIP2008普及组第3题 传球游戏 时间限制: 1 Sec  内存限制: 128 MB提交: 29  解决: 16[提交][状态][讨论版][命题人:外部导入] 题目描述 上体育课的时候,小蛮的老 ...

  6. NOIP2004普及组第3题 FBI树

    /* 1106: NOIP2004普及组第3题 FBI树 时间限制: 1 Sec 内存限制: 128 MB 提交: 10 解决: 9 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 我 ...

  7. 动态规划 洛谷P1048 [NOIP2005 普及组] 采药

    洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...

  8. 洛谷 P1070 道路游戏(noip 2009 普及组 第四题)

    题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 nn个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 nn个机器人工厂编 ...

  9. CSP-J2019 NOIP普及组初赛真题(阅读程序部分)

    阅读程序(程序输入不超过数组或字符串定义的范围:判断题正确填√,错误填×:除特殊说明外,判断题1.5分,选择题3分,共计40分) #include <cstdio> #include &l ...

随机推荐

  1. mysql 出现Host 'localhost' is not allowed to connect to this MySQL server 错误

    MySql数据库:Host 'localhost' is not allowed to connect to this MySQL server 修改mysql的root密码后,出现Host 'loc ...

  2. Python 文本相似度分析

    环境 Anaconda3 Python 3.6, Window 64bit 目的 利用 jieba 进行分词,关键词提取 利用gensim下面的corpora,models,similarities ...

  3. storm 入门介绍(持续更新)

    storm的集群表面上看和hadoop的集群非常像.但是在Hadoop上面你运行的是MapReduce的Job, 而在Storm上面你运行的是Topology.它们是非常不一样的 — 一个关键的区别是 ...

  4. Xcode 8 GM 编译缺失 /Users/usr/lib/libresolv.9.dylib

    原因是操作系统的文件与手机需要的不同. 解决办法是将iOS DeviceSupport里当前手机版本的Symbols的libresolv.9.dylib文件,代替编译失败项目的Build Phases ...

  5. B树, B-树,B+树,和B*树的区别

    B树: B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中: 否则,如果查询关键字比结点关键字小,就进入左儿子:如果比结点关键字大,就进入 右儿子:如果左儿子或右儿子的指针为空, ...

  6. s​h​e​l​l​中​条​件​判​断​i​f​中​的​-​z​到​-​d​

    shell中条件判断if中的-z到-d的意思 2011-09-05 10:30 [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为 ...

  7. 初始化spring容器的几种方法

    package ssh.spring; import java.io.IOException; import org.springframework.beans.factory.BeanFactory ...

  8. Node负载能力测试

    需求很简单,就是提供一个服务接口收集端上传来的日志文件并保存,要求能承受的QPS为5000. 以前从来都没考虑过Node服务的负载能力,用 koa + co-busboy 接受上传文件请求并用 fs ...

  9. 2017.11.15 Add a parameter –serial <serial no> to the Target field.

    1 exe创建快捷方式,并且加后缀  program --serial 50114130   这是Win里面的一种调用说明. Please note that the programming logs ...

  10. Python爬虫----抓取豆瓣电影Top250

    有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息. 1.观察url 首先观察一下网址的结构 http://movie.douban.com/to ...