Description
描述
There is sequence 1, 12, 123, 1234, ..., 12345678910, ... . Given first N elements of that sequence. You must determine amount of numbers in it that are divisible by 3.
给定数列 1, 12, 123, 1234, ..., 12345678910, ...的前N个元素。你需要判断其中一共有多少个元素能够被3整除。
Input
输入
Input contains N (1<=N<=231 - 1).
输入文件包含N(1<=N<=231 - 1)。
Output
输出
Write answer in output file.
将答案输出在输出文件上。
Sample Input
样例输入
4
Sample Output
样例输出
2
Analysis
分析
由于一个数对3取模恒等于这个数各个位上数字之和对3取模。
因此,非常容易想到的方法是找规律:
项数N | 数列 | 除以3的余数 | 答案ans |
1 | 1 | 1 | 0 |
2 | 12 | 0 | 1 |
3 | 123 | 0 | 2 |
4 | 1234 | 1 | 2 |
5 | 12345 | 0 | 3 |
6 | 123456 | 0 | 4 |
7 | 1234567 | 1 | 4 |
8 | 12345678 | 0 | 5 |
9 | 123456789 | 0 | 6 |
由上述表格,我们可以大致的看出规律,即:
- N % 3 == 1 => ans不变
- N % 3 == 0, 2 => ans + 1
有了上述的讨论,我们可以很容易的写出一个暴力算法,但是考虑到N的数据范围比较大,这并不是一个非常好的选择。
我们可以推导出数学公式来求解这个问题。观察上表(下面的除法为C++意义中的整除):
- N % 3 == 0 => ans = 2 * N / 3
- N % 3 == 1 => ans = 2 * N / 3
- N % 3 == 2 => ans = 2 * N / 3 + 1
把上述公式归纳成一个公式,即为ans = 2 * N / 3 + (N % 3 == 2),此处N % 3 == 2的返回值为真、假,分别对应着1、0。
Solution
解决方案
#include <iostream>
using namespace std;
int main()
{
int N;
cin >> N;
cout << N / 3 * 2 + (N % 3 == 2) << endl << endl;
return 0;
}
这是一道较为简单的数学找规律的题目,但是找到规律以后如何推导得到最终的数学表达式还是有一定的难度的。