博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
离线 + 位优化 - SGU 108 Self-numbers 2
阅读量:7073 次
发布时间:2019-06-28

本文共 2182 字,大约阅读时间需要 7 分钟。

SGU 108 Self-numbers 2 


 

Mean: 

略有这样一种数字:对于任意正整数n,定义d(n)为n加上n的各个位上的数字(d是数字的意思,Kaprekar发明的一个术语)。如:d(75) = 75 + 7 + 5 = 87。给定任意正整数n,你可以构建出无限的整数递增:n, d(n), d(d(n)), d(d(d(n))), ……举个例子,你从33开始,那么下一个数就是33 + 3 + 3 = 39, 再下一个就是39 + 3 + 9 = 51, 接着就是 51 + 5 + 1 = 57, 那样就生成了一个序列: 33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ... 这里n叫做d(n)的母数 上面的数列中,33是39的母数,39是51的母数,51是57的母数,以此类推……有些数字不止一个母数,比如101有两个母数,91和100。没有母数的数字就叫做self-number。让a[i]成为第i个self-number。现在存在13个小于100的self-number: 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 和 97. (第一个 self-number是a[1]=1, 第二个是 a[2] = 3,  第十三个是 a[13]=97).

analyse:

此题比较BT,内存卡得比较紧,做的时候需要考虑如何压缩内存,不过还是1.5s把它过了.

主要方法就是用个滚动数组用类似筛法做,题目倒不是很难.

Time complexity: O(N)

 

view code

/**
* -----------------------------------------------------------------
* Copyright (c) 2016 crazyacking.All rights reserved.
* -----------------------------------------------------------------
*       Author: crazyacking
*       Date  : 2016-01-06-19.55
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using
namespace
std;
typedef
long
long(
LL);
typedef
unsigned
long
long(
ULL);
const
double
eps(
1e-8);
pair
<
int
,
int
>
q
[
5010
];
bool
f1
[
64
],
f2
[
64
];
int
ans
[
5010
];
int
num
,n
,
m;
int
main()
{
   
scanf(
"%d %d"
,
&n
,
&
m);
   
for (
int
i
=
0;
i
<
m;
++
i)
   
{
       
scanf(
"%d"
,
&
q
[
i
].
first);
       
q
[
i
].
second
=
i;
   
}
   
sort(
q
,
q
+
m);
   
int
pos
=
0;
   
memset(
f1
,
true
,
sizeof(
f1));
   
memset(
f2
,
true
,
sizeof(
f2));
   
for (
int
i
=
1;
i
<=n;
++
i)
   
{
       
if (
i
%
64
==
0)
       
{
           
memcpy(
f1
,
f2
,
64);
           
memset(
f2
,
true
,
sizeof(
f2));
       
}
       
if (
f1
[
i
%
64
])
       
{
           
num
++;
           
while (
q
[
pos
].
first
==
num)
ans
[
q
[
pos
++
].
second
]
=
i;
       
}
       
int
tmp
=
0
,
j
=
i;
       
while (
j
>
0)
       
{
           
tmp
+=
j
%
10;
           
j
/=
10;
       
}
       
if (
tmp
+
i
%
64
>=
64)
f2
[(
tmp
+
i
%
64)
%
64
]
=
false;
       
else
f1
[
tmp
+
i
%
64
]
=
false;
   
}
   
printf(
"%d
\n
"
,
num);
   
for (
int
i
=
0
,
j;
i
<
m;
++
i)
   
{
       
printf(
"%d"
,
ans
[
i
]);
       
if (
i
!=
m
-
1)
printf(
" ");
       
else
printf(
"
\n
");
   
}
   
return
0;
}

 

转载于:https://www.cnblogs.com/crazyacking/p/5107479.html

你可能感兴趣的文章
Spark Streaming源码解读之No Receivers
查看>>
使用背景图的div宽高自适应
查看>>
sql注入工具
查看>>
MongoDB 开启用户认证登录
查看>>
ADO.NET操作数据库(一)
查看>>
指针与引用的本质区别
查看>>
Auto Layout 使用心得(五)—— 根据文字、图片自动计算 UITableViewCell
查看>>
M3U8在线视频文件下载合成MP4视频(自己想看电影)
查看>>
HTML5的布局的使用
查看>>
hdu 1068 二分图的最大匹配匈牙利算法
查看>>
一个IT人的非典型职场十年 (4)
查看>>
Netty之Recycler实现对象池
查看>>
Netty5入门学习笔记004-使用Netty传输POJO对象(上)
查看>>
Eclipse的快捷键总结
查看>>
RandomAccessFile相关(读写文件) --本文的正确性有待您验证。
查看>>
结构体对齐详解
查看>>
关于索引的基础知识
查看>>
全民WIFI上网计划
查看>>
Spring和SpringMVC父子容器关系初窥
查看>>
【原创】MySQL Proxy - read_query()
查看>>