真如这题的discuss里说的,细节决定成败……&*%……&*%&*……&*&*#¥@
太恶心了。。。做了好久!
最后打表都一样提交WA,不支持long long的缘故= =。。。有的地方没改成__int64 = =。。。
其实这题就是问你比N小的数是任意位都小于等于 3 && 个位小于3的数字。
这样的数有多少个 = =。。。
卡shi我了。。。
我是这么做的,比如15200,先算10000以内有多少个这样的数,然后算10000 - 15000以内,因为已经遇到5了,那么后面肯定不能再算15000 - 15200里的了。
找这种数的时候,明显个位只能取 0 1 2 ,其他位都可以取0 1 2 3 。。。= = 然后就自己想吧 = =。。
细节很!!!恶心!
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
#define STOP system("pause")
using namespace std;
char s[15];
bool check(__int64 a, __int64 b, __int64 c)
{
while( a || b || c )
{
if( a%10 + b%10 + c%10 >= 10)
return false;
a /= 10;
b /= 10;
c /= 10;
}
return true;
}
int solve(__int64 x)
{
char s[15];
sprintf(s, "%I64d", x-1);
int len = strlen(s);
__int64 ans = 1;
for(int i=0; i<len-1; i++)
{
if( s[i] - '0' >= 3 )
ans *= 4;
else
ans *= (s[i] - '0' + 1);
}
if( s[len-1] - '0' >= 3 )
ans *= 3;
else
ans *= (s[len-1] - '0' + 1);
if( check(x, x+1, x+2) )
ans++;
return ans;
}
int main()
{
int ans;
__int64 k;
while( ~scanf("%I64d", &k) )
{
sprintf(s, "%I64d", k);
int len = strlen(s);
int sum = 0;
bool f = false;
int o = 0;
for(int i=0; i<len; i++)
{
if( f ) continue;
if( s[i] == '0' ) continue;
if( s[i] - '0' > 3 ) f = true;
__int64 n = 1;
for(int l=0; l<len-i-1; l++)
n *= 10;
__int64 p = (s[i] - '0')*n;
o++;
sum += solve(p);
}
if( check(k, k+1, k+2) )
sum--;
printf("%d\n", sum - o + 1);
}
return 0;
}