曾记否,到中流击水,浪遏飞舟。|

Moyyer_suiy

园龄:2年8个月粉丝:4关注:18

5.29 数学模拟赛 1

A.之前写过题解,不说了。


B.N 钱买 N 鸡,要求 O(n)。

思路还是和之前一样,但是提供一种新写法:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
int ans[29] = {1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int main()
{
  scanf("%lld", &n);
  printf("%lld\n", n / 28 + ans[n % 28]);
}

把式子列出来,把分数化掉,会得到一个关于 4 和 7 的奇怪式子。通过打表找规律会发现到 4 * 7 的倍数时就是统计答案的新一层。至于代码里 ans[29] 那些也是通过打表体现 4 和 7 之和等可能性。


C.简述题目:给你一个序列,对于每个元素,其答案是:序列中能把它整除掉的元素个数,对于每个元素求答案。

算是暴力吧:出现的每个数字用桶装一遍,然后对于每个数字找一遍因数加上答案即可。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
int ys[N];
int ans[N], tong[N * 10], a[N];
int main()
{
  scanf("%d", &n);
  for(int i = 1; i <= n; i ++ )
  {
  scanf("%d", &a[i]);
  tong[a[i]] ++;
  }
  for(int i = 1; i <= n; i ++ )
  {
    int tot = 0;
    for(int j = 1; j * j <= a[i]; j ++ )
    {
      if(a[i] % j == 0)
      {
        ys[++ tot] = j;
        if(j != a[i] / j) ys[++ tot] = a[i] / j;
      }
    }
    for(int j = 1; j <= tot; j ++ )
    {
      ans[i] += tong[ys[j]];
      ys[j] = 0;
    }
  }
  for(int i = 1; i <= n; i ++ ) printf("%d\n", ans[i] - 1);
}

顺便简单说一嘴试除法求因数:因为因数总是成对出现,所以若 n | d,则(n / d) | d(n表示整除),因此我们只需要枚举一边就可以了:化简式子,知道求因数时只需要枚举到根号 n。还是很简单捏。

还可以根号分治,优美的暴力!但是本题不太适用,跑的会比较慢。主要原因是我不会写()

题解鸽了很久没有一篇写完的了,所以为这伟大的一篇新鲜出炉的题解撒花表示热烈庆祝!()

本文作者:Moyyer_suiy

本文链接:https://www.cnblogs.com/Moyyer-suiy/p/17441541.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Moyyer_suiy  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起