蓝桥杯-苏苏的幸运数字7

问题描述
苏苏的家乡相传有这样一个说法,说是如果这个人是某月出生的,那么这个人的幸运数字就是这个月份,因此七月份出生的苏苏一直认为自己的幸运数字就是七。
有一天,苏苏在翻看数学有趣知识笔记的时候,看到了这样一个有趣的题目,题目中写到,对于这样n个数字,1², 2²,3²,4²,...n²,一定有方法能够使得这n个数除以一个数字之后的余数被很快找出来,并且也能够快速找出这些余数出现的次数。
现在苏苏想用自己的幸运数字七来验证一下这个结论,懒惰的苏苏想请你帮她计算一下,对于这n个数字,除以七之后的余数有多少种,这些余数分别是多少,每种余数出现的次数是多少(余数按从小到大输出)?
输入格式
第一行包含一个整数n,表示数字的个数。
输出格式
第一行包含一个整数num,表示上述n个数字除以七之后的余数的种数。
接下来num 行,每行包含两个整数a,b,分别表示余数和这个余数出现的次数(余数按从小到大输出)。

输入样例:

2

输出样例:

2
1 1
4 1

解题思路

通过1²/%7=1,2²%7=4,3²%7=2,4²%7=2,5²%7=4,6²%7=1,7²%7=0……,可知该 前n个数是以7个数为一次循环 ,那么此时可以使用数组a[]将其储存,那么接下来可以遍历前n个数用 map<int,int> 储存出现的余数同时储存其出现的个数,并进行从小到大的排序 ,同时还要注意题目所给数据大小问题,n不超过10^18,那么为了尽可能的减小时间复杂度,我们可以对n分两种情况进行讨论,一是n<=7可直接遍历,二是n>7时可以先算出n/7=x( 注意因为n可能非常大,所以x应使用long long类型 ),因为每次循环中1、2、4都是两个,0是一个,所以可以先用map存储前x组的数据,最后进行n%7次的遍历,最后再输出就可以了

#include <iostream>
#include <map>
using namespace std;
map<int, long long int> s;
int main()
{
  int a[7] = {1, 4, 2, 2, 4, 1, 0};
 long long  int n;
  cin >> n;
  if(n<=7)
  for (long long int i = 1; i <= n; i++)
  {
    if (i % 7 == 1 || i % 7 == 6)
    {
      s[a[0]]++;
    }
    if (i % 7 == 2 || i % 7 == 5)
      s[a[1]]++;
    if (i % 7 == 3 || i % 7 == 4)
      s[a[2]]++;
    if (i % 7 == 0)
      s[a[6]]++;
  }
  else
  {
   long long int cs=n/7;
   s[a[0]]=2*cs;
   s[a[1]]=2*cs;
   s[a[2]]=2*cs;
   s[a[6]]=cs;
   int sum=n%7;
   for(int i=1;i<=sum;i++)
   {
      if (i % 7 == 1 || i % 7 == 6)
    {
      s[a[0]]++;
    }
    if (i % 7 == 2 || i % 7 == 5)
      s[a[1]]++;
    if (i % 7 == 3 || i % 7 == 4)
      s[a[2]]++;
    if (i % 7 == 0)
      s[a[6]]++;
   }
  }
  map<int,long long  int>::iterator it = s.begin();
  cout << s.size() << endl;
  for (; it != s.end(); it++)
  {
    if (it->second > 0)
      cout << it->first << " " << it->second << endl;
  }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperRandi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值