第六届蓝桥杯代码填空——循环节长度

62 篇文章 0 订阅
11 篇文章 5 订阅

1.题目描述:


要求你在下述代码填充

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int f(int n, int m) {
    n = n % m;
    vector<int> v;
    for(;;) {
        v.push_back(n);
        n *= 10;
        n = n % m;
        if (n == 0) return 0;
        if (find(v.begin(), v.end(), n) != v.end()) {
            // 在下面填入代码

        }
    }
}
int main() {
    int n, m;
    cin >> n >> m;
    cout << f(n, m) << endl;
    return 0;
}

2.分析

什么是循环节题目大概已经说了,就是所得的数有一个循环的长度,之后的数等一次循环节开始后,又开始一次循环节,一直循环。因为此道题目是代码填空题,已经大致给出算法思想,拿题目例子示例input:11 13 output:6
我们首先对11%13 mod :11
将11存到v中,此时v只有一个元素
然后11*10 = 110
110%13 = 6
然后拿6在数组v中找是否有相同的元素发现
if (find(v.begin(), v.end(), n) != v.end())
此条件不满足,这条判断语句就是指在数组长度范围内,是否在数组中找到了n,找到了则为真此条件,否则为假。
那么我们求循环节,比如循环节为1234563456那么循环节就是3456,然而我们可以从第二个3开始与已经存在的数组元素判断,如果存在相同元素,那么通过find函数返回该元素下标,比如1234563456第一次3的下标为2,循环节为3456为4,然后我们通过v.size()或者v.end()减掉返回的下标2就是循环节长度

所以这里应该填的是

return (int)(v.end() - find(v.begin(),v.end(),n));
//或者是
return v.size() - (find(v.begin(),v.end(),n) - v.begin());

3.总结:

这道题目首先你要对STL的不定长数组vector有所了解,find(v.begin(),v.end(),n)表示在v这个数组长度范围内找到是否有n这个元素,找到则返回数组下标,注意数组下标是0开始的。
说一说上述答案

a.return (int)(v.end() - find(v.begin(),v,end(),n));这个返回的就是循环节长度.
注意:v.end()是指数组的末尾元素,返回的是迭代器类型
你不能直接用整型输出,你可以使用(v.end() - v.begin())输出即可,这样返回就可以是一个整型。
v.begin() 返回一个迭代器,它指向容器v的第一个元素
所以,为0
v.end() 返回一个迭代器,它指向容器v的最后一个元素的下一个位置
所以,为6
而find方法返回的也是迭代器类型
使用v.end() - find(…)在强转类型就是返回整型
如果你使用v.size() - find(..)编译器会报错,因为v.size()返回数组的长度就是int型,所以会报错

b.return v.size() - (find(v.begin(),v.end(),n) - v.begin());
这个没有用到(int)强转,是因为(find(v.begin(),v.end(),n) - v.begin())将迭代器类型转为整型了
原因:
不论vector对象本身是否是常量,返回值都是const_iterator
const_iterator是声明iterator指向的对象是常量,即iterator指向常对象,其本身可以变
如果vector对象不是常量,既可以使用iterator也可以使用iterator_const
iterator能读写vector::iterator中的元素

 

欢迎关注Blog:http://47.107.118.184

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值