Mean:
定義這樣一種數列:1,12,123..
給出一個n,求這個數列中能被3整除的數的個數.
analyse:
這道題可以用分析的方法解決:
對于正整數k,k+1,k+2總有
k+(k+1)+(k+2)
=k+k+1+k+2
=3k+3
=3(k+1)
3(k+1)可以被3整除,而且,一個數是否能被3整除表現為它的各位數字之和能否被三整除.
這就意味着對于一個數12345678910111213...k(連寫),我們可以從後面開始,把數字三個一組劃去,剩下三個或不足三個數為止,那麼剩下的數對于3的整除情況和原數一緻.
例如
123456789
劃去一組 123456
劃去一組 123
12可以被3整除,那麼123456789也可以。又比如
1234567891011121314
劃去一組 1234567891011
劃去一組 12345678
劃去一組 12345
劃去一組 12
123可以被3整除,那麼1234567891011121314也可以。再比如
1234
劃去一組 1
1不能被3整除,1234也不能。
我們可以歸一下類,對于一個由前k個正整數連寫成的數m,如果k與3相除,餘數是0或2(分别對應上述的第一和第二種情況),那麼m可以被3整除;如果餘數是1,那麼m不能被3整除。
綜上題目可以轉化為求出1-n之間有多少個能被3整除或被三整除餘2的數,這就不難計算了。比較簡便的方法是找出1-n之間被3除餘數為1的數有多少個,記為x,那麼n-x即為所求。
現在的主要沖突是求出x,先觀察前幾個正整數:
1 2 3 4 5 6 7 8
^ ^ ^
其中被标記的數被3除,餘數是1。可以發現,從1開始,需要統計的數在數列中出現的周期是3,而且這些數總是出現在每個周期的第一位,是以:對于一個長度為n的數列,它含有的周期的個數(n/3向上取整數)就是上文所提的x。
注意:由于這些數總是出現在每個周期的第一位,是以不滿一周期(n被3除有餘數)按照一完整周期進行計算。
Time complexity: O(1)
view code
/**
* -----------------------------------------------------------------
* Copyright (c) 2016 crazyacking.All rights reserved.
* Author: crazyacking
* Date : 2016-01-06-17.53
*/
#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);
int main()
{
int n = 0;
scanf("%d", &n);
if(n % 3 == 0)
{
printf("%d", n/3*2);
}
else
printf("%d", n/3*2+n%3-1);
return 0;
}