} /** * 我的基于递归的算法 */ public static int ldhCount(int num) { if (num < 10) { // 个位数 return (num > 0) ? 1 : 0; } else { // 非个位数 int sum = 0; // 记录汇总数 int n = String.valueOf(num).length() - 1; // 计算当前数值的数量级 int p = (int) Math.pow(10, n); // 本数量级 10^n 的值 int a = num / p; // 首位数字是啥 int y = num - a * p; // 余数 int up = ldhCount(y); // 迭代计算低一个数量级的1的个数 int tmp = n * ((int) Math.pow(10, n - 1)); // 该公式所计算的值经常用,先放起来
public class Test { public static void main(String[] args) { int n = 1010; int result = 0; int i = 1; boolean flag = true; if (n > 0) { while (i < n + 1) { String text = new Integer(i).toString(); if (text.indexOf("1") != -1) { result++; System.out.print(text + " "); } if (flag) { i += 9; flag = false; } else { i += 1; flag = true; } } } System.out.println("\n共出现了:" + result); } }
就是个数字游戏而已,找好规律直接编程就行了,是数学问题,不是算法问题 #include <stdio.h> #include <stdlib.h>int main(int argc, char *argv[]) { if (2 != argc) {printf("usage:[%s] num\n", argv[0]); return -1;}; int num = abs(atoi(argv[1])); int count = 0; while (10 <= num) { int bits = 0, numtmp = num, curint = 1;; while(1) { curint *= 10; ++bits; if (10 >(numtmp = numtmp/10)) break; } if (numtmp > 1) count += curint; else count += ((num%curint) + 1); count += bits*((curint/10)*(num/curint)); num = num%curint; } if (num >= 1) ++count; printf("%d\n", count); return 0; }
totals[10]={0};//依次保存从0到9, 10个数字出现的次数// for ( int num = 0; num <= setting_num; num++ ) { string str = int2string( num ); for ( int i = 0; i < str.length(); i++ ) { int index = (int)(str[i]-'0'); totals[index]++; } }
0--13生成的字符串:012345678910111213
期中1匹配次数:6次源码:
import java.util.regex.*;
public class PapaverFlower { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
PapaverFlower pf = new PapaverFlower();
//传递一个整数13
System.out.println("期中1匹配次数:"+pf.getNumberOne(13)+"次");
}
//输入要匹配到整数
public int getNumberOne(int num){
int mapSum = 0;//定义一个计数器
String regex = "[1]";//正则
String textStr = "";
//通过传递过来的数,生成字符串
for(int i = 0; i <= num; i ++){
textStr += i;
}
System.out.println("0--"+num+"生成的字符串:"+textStr);
//使用正则表达式,查找(没有便利数组,逐个获取)
Matcher m = Pattern.compile(regex).matcher(textStr);
while(m.find()){
++ mapSum;
}
return mapSum;
}}
那么直接用
"012345467891011121314".split("1").length();
10^n里包含 n*10^(n-1)+1个1
也就是 10的n次方 包含 n乘以10的n-1次方+1 个1
首先看看规律 10^n里包含 n*10^(n-1)+1个1
即
1 包含 1个1
10 包含 2个1
100 包含 21个1
1000 包含 301个1
10000 包含 4001个1
举例说明,取100和1000之间,知道100和1000相差301-21=280个1
而我们知道100-200之间,百位数是1有100个,所以去掉1开头的数 280-100=180
而200-999每100个数,它们的1的个数是一样的,所以它们之间每100个数有 180/9 = 20 个1
同样的,可以知道2000-9999它们之间每1000个数有 (4001-301-1000)/9 = 300 个1
20-99它们之间每10个数有 (21-2-10)/9 = 1 个1
这样,一个数,比如 abc=a*100+b*10+c,分别计算它的每个位数a,b,c所包含的1就可以了
我的进展——我分析了1出现的次数:
1——9: X1(也就是01) 1
1——99: X1 1X (1*10)+10
1——999: 1XX 1X X1 (1*10+10)*10+100
1——9999: 1XXX 1XX 1X X1 ((1*10+10)*10+100)*10+1000
即每次都是上面高手说的函数10的N次方里面有(N*10的N-1次方个+1)个1。
中午吃饭的时候我认为只剩下了两个思路。
第一就是把数拆开,分成几个相加的数,这个拆的方法我试了好几种都觉得不完美,现在还在试。
第二,其实也是拆,就是每次求余,把每一个数写出来,再根据数的位数进行计算。比如:13可以拆为1和3,因为它是两位数,有根据X1,1X的方法,可以计算为1*(1+1)+1*(3+1)=6,也就是XY的一的个数为:1*(X+1)+1*(Y+1)这样的话也就有特例,如果是几十的数而不是十几的数比如23,我们就要1*(2+1)+10=13了,几十的就成了1*(X+1)+10。如果这样分析我们似乎还要用第一种方法拆数,才可以做最后计算。
现在分析到三位数依然要考虑很多东西,正在解决中
100:直接公式计算出来(n*10^(n-1)+1)
101~199:直接公式计算出来(公式没研究)
201~(a)00:直接公式计算出来 (a-1)*(跟前一个公式的区别是少了整整 100 个1)
a00~abc:递归调用来计算bc的这里面免不了要些if判断。
OK,回归主题。你做做试试看啊,十五楼的哪一组计算我也看得出来用递归,不过中间有很多需要判断的地方,复杂的无法处理。做做试试啊。
public static void main(String a[]){
Scanner sc=new Scanner(System.in);
int read=sc.nextInt();
String in=new Integer(read).toString();
char readIn[]=in.toCharArray();
//count(readIn);
int sumsum=count(readIn);
System.out.println(sumsum);
}
public static int count(char a[]){
int sum=0;
double c=a.length;
int[] b=new int[a.length];
for(int i=0;i<a.length;i++){
b[i]=a[i]-'0';
}
for(int i=0;i<Math.pow(2.0, c);i++){
String er=parse(i,a.length);
char bufferchar[]=er.toCharArray();
int countOne=0;
int local=1;
for(int x=0;x<bufferchar.length;x++){
if((bufferchar[x]-'0')==1)
countOne++;
else{
local*=b[x];
}
}
if(countOne==bufferchar.length)
sum+=bufferchar.length;
else
sum+=local*countOne;
}
return sum;
}
public static String parse(int x,int y){
StringBuilder sb=new StringBuilder();
int g=0;
for(int i=x;;i=i/2){
if(i/2==0){
sb.append(i%2);
break;
}
sb.append(i%2);
}
for(int i=sb.length();i<y;i++){
sb.append(0);
}
return sb.reverse().toString();
}
}
这回这个不是便利的,是嵌套递归
运行结果:0到100共有21个1
源码:
public class PapaverFlower2 {
String AddNumber ="";
static int saveNum = 0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//输入你要测试的数字
saveNum = 100;
new PapaverFlower2().doNest(saveNum);
} public void doNest(int num){
AddNumber += ""+num;
num -= 1;
if(num < 0){
System.out.println("0到"+saveNum+"共有"+(AddNumber.split("1").length - 1)+"个1");
}else if(num >=0) {
doNest(num);
}
}}
给你一段代码吧public class Test {
public static void main(String[] args) throws Throwable {
int num = 13; //测试数据,可以自己修改
System.out.println(countOne(num)); //打印结果
} public static int countOne(int num) { //计算1的个数
if (num < 1) return 0;
int org = num, count = 0, pow = 1, dig = 0, m = 0;
//pow代表10的n次方,dig代表n,m代表每位的数字
while (num > 0) { //从个位开始循环取每位数字
m = num % 10; //获取每位数字
if (m > 0) { //如果该数字不为0
count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
}
if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
count += org % pow;
} else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
count += pow - 1; //首先之前说明例子中的100-200之间的最高位为1的个数pow
//这里为何要-1,因为在A的地方,100已经被我们计算过一次了
count += (m-1)* dig * pow / 10; //然后这里就是之前例子中的200-999之间的
//每100个数相差的1的个数
}
num /= 10; //原数右移,为了取最低位的数字
pow *= 10; //10的n次方增加,因为没计算一次,位数相当于左移,即从个位到百位等等
dig++; //n次方的n增加
}
return count; //返回值
}
}
虽然没有明着遍历,递归每次调用这个方法,num都会减1,和遍历一样。
谢谢。
a : x 位整数
b : y 位整数
n = x- y;
int sum +=0;
for(int i =1;i< n-1 ;i++)
{
第一种情况: 整数b在构成后数字的前面 例如 12,构成 121,122,125等
for(int j = 1; j <= i;j++)
{
sum += Math.paw(10,j);
}
第二种情况: 整数b在构成后数字的中间 例如 12 构成 112,212,312等 有重复的情况,但是必须考虑出现重复的数字 例如 1212 12112 121212等数字
}
接着考虑 有b数字构成x位数的情况
情况和上面的一样两种:不过要考虑构成后数字与A数字的大小
* @param args
*/
public static void main(String[] args) {
System.out.println("1=" + countOne(1) + " " + ldhCount(1));
System.out.println("9=" + countOne(9) + " " + ldhCount(9));
System.out.println("13=" + countOne(13) + " " + ldhCount(13));
System.out.println("20=" + countOne(20) + " " + ldhCount(20));
System.out.println("99=" + countOne(99) + " " + ldhCount(99));
System.out.println("100=" + countOne(100) + " " + ldhCount(100));
System.out.println("101=" + countOne(101) + " " + ldhCount(101));
System.out.println("109=" + countOne(109) + " " + ldhCount(109));
System.out.println("113=" + countOne(113) + " " + ldhCount(113));
System.out.println("120=" + countOne(120) + " " + ldhCount(120));
System.out.println("121=" + countOne(121) + " " + ldhCount(121));
System.out.println("199=" + countOne(199) + " " + ldhCount(199));
System.out.println("209=" + countOne(209) + " " + ldhCount(209));
System.out.println("213=" + countOne(213) + " " + ldhCount(213));
System.out.println("220=" + countOne(220) + " " + ldhCount(220));
System.out.println("1000=" + countOne(1000) + " " + ldhCount(1000));
System.out.println("1001=" + countOne(1001) + " " + ldhCount(1001));
System.out.println("1009=" + countOne(1009) + " " + ldhCount(1009));
System.out.println("1010=" + countOne(1010) + " " + ldhCount(1010));
System.out.println("1013=" + countOne(1013) + " " + ldhCount(1013));
System.out.println("1099=" + countOne(1099) + " " + ldhCount(1099));
System.out.println("1100=" + countOne(1100) + " " + ldhCount(1100));
System.out.println("1110=" + countOne(1110) + " " + ldhCount(1110));
System.out.println("1111=" + countOne(1111) + " " + ldhCount(1111));
System.out.println("1313=" + countOne(1313) + " " + ldhCount(1313));
System.out.println("9999=" + countOne(9999) + " " + ldhCount(9999));
System.out.println("13913=" + countOne(13913) + " " + ldhCount(13913));
System.out.println("913913=" + countOne(913913) + " " + ldhCount(913913));
System.out.println("3913913=" + countOne(3913913) + " " + ldhCount(3913913));
System.out.println("13913913=" + countOne(13913913) + " " + ldhCount(13913913));
System.out.println("113913913=" + countOne(113913913) + " " + ldhCount(113913913));
System.out.println("213913913=" + countOne(213913913) + " " + ldhCount(213913913));
System.out.println("313913913=" + countOne(313913913) + " " + ldhCount(313913913));
System.out.println("413913913=" + countOne(413913913) + " " + ldhCount(413913913)); // 似乎前者溢出了
System.out.println("513913913=" + countOne(513913913) + " " + ldhCount(513913913)); // 似乎前者溢出了
System.out.println("713913913=" + countOne(713913913) + " " + ldhCount(713913913)); // 似乎前者溢出了
System.out.println("913913913=" + countOne(913913913) + " " + ldhCount(913913913)); // 似乎前者溢出了
} /**
* 我的基于递归的算法
*/
public static int ldhCount(int num) {
if (num < 10) { // 个位数
return (num > 0) ? 1 : 0;
} else { // 非个位数
int sum = 0; // 记录汇总数
int n = String.valueOf(num).length() - 1; // 计算当前数值的数量级
int p = (int) Math.pow(10, n); // 本数量级 10^n 的值
int a = num / p; // 首位数字是啥
int y = num - a * p; // 余数
int up = ldhCount(y); // 迭代计算低一个数量级的1的个数
int tmp = n * ((int) Math.pow(10, n - 1)); // 该公式所计算的值经常用,先放起来
sum = tmp; // 从 000~999 的1的个数
/* 下面这段if中的某些语句可以抽出来公用,但是这样会导致看不清楚思路,我就保留原样了 */
if (a == 1) {
sum += y + 1 + up; // 1000 ~ 1bcd中,首位字符出现1为(y+1)次,其它字符(?000 ~ ?bcd)出现为up(迭代)次
} else if (a == 2) {
sum += p + tmp; // 从 1000~1999,首位字符出现1为(10^n)次,其它字符用公式tmp(000~999)
sum += up; // 从 2000~2bcd
} else {
sum += p + tmp; // 从 1000~1999,首位字符出现1为(1000)次,其它字符用公式tmp(000~999)
sum += (a - 2) * tmp;// 从 2000~(a-1)999,实际上就是 a-2 次tmp(000~999),因为首位数1和首位数a的情况已经另行处理了
sum += up; // 从 a000~abcd
} return sum;
}
} /**
* 大牛qybao基于循环(其实应该是递推)的算法
*/
public static int countOne(int num) { //计算1的个数
if (num < 1)
return 0;
int org = num, count = 0, pow = 1, dig = 0, m = 0;
//pow代表10的n次方,dig代表n,m代表每位的数字
while (num > 0) { //从个位开始循环取每位数字
m = num % 10; //获取每位数字
if (m > 0) { //如果该数字不为0
count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
}
if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
count += org % pow;
} else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
count += pow - 1; //首先之前说明例子中的100-200之间的最高位为1的个数pow
//这里为何要-1,因为在A的地方,100已经被我们计算过一次了
count += (m - 1) * dig * pow / 10; //然后这里就是之前例子中的200-999之间的
//每100个数相差的1的个数
} num /= 10; //原数右移,为了取最低位的数字
pow *= 10; //10的n次方增加,因为没计算一次,位数相当于左移,即从个位到百位等等
dig++; //n次方的n增加
}
return count; //返回值
}
}
【计算结果】
1=1 1
9=1 1
13=6 6
20=12 12
99=20 20
100=21 21
101=23 23
109=31 31
113=40 40
120=53 53
121=55 55
199=140 140
209=141 141
213=146 146
220=152 152
1000=301 301
1001=303 303
1009=311 311
1010=313 313
1013=320 320
1099=420 420
1100=422 422
1110=444 444
1111=448 448
1313=780 780
9999=4000 4000
13913=10100 10100
913913=560100 560100
3913913=3360100 3360100
13913913=14274014 14274014
113913913=108187928 108187928
213913913=274274014 274274014
313913913=354274014 354274014
413913913=4777285 434274014 // 似乎前者溢出了
当然的,他的算法思路从性能上而言比我的好多了。我的算法主体思路其实就在20楼。总的来说,是一种收获,嗯。
估计是这句话导致的溢出:
count += (m - 1) * dig * pow / 10
因为是先乘再除了,修改的话大概是:
count += (m - 1) * dig * (pow / 10)
不过溢出并不是问题,就算最了不起无非是改为long而已。
而用了幂运算的计算代价肯定是要高的,qybao则巧妙的一直利用pow *= 10这种方式逐步实现幂运算的类似效果。
“这个题目有个简单的方法”
“每一位,当其不是首位的时候,出现的次数就是10的整数倍,而1出现的频率是1/10”
“计算0-10^n-1时,1的个数,等于非首位字符个数/10再加上首位中的1出现的次数”
“而首位的出现次数,也可以用类似的统计方法来计算”
“最终计算的时候,例如0-3361,可以分解为0-999; 1000-2999;3000-3299;3300-3359;3360-3361”
“第一部分是从0-10^n-1,剩余部分,第一部分是从10^n-1到M*10^n,其余部分的分块等于除首位的有效位的个数(或+1)”
“我说的这个方法关键是概率,也可以按照其他方法来划块.”
如N=123456,x=3,d[3]=4,p[3]=100, h[3]=123, t[3]=56
有
d[x]==0时, c[x]=h[x]*p[x];
d[x]==1时,c[x]=h[x]*p[x]+t[x]+1;
d[x]>1时,c[x]=(h[x]+1)*p[x];
m
而OneSum= 总和: c[x]
x=1
当然不行,你试试 11111 或者 1001 或者 100 等等.楼主说不遍历,那是胡扯,不遍历,谁知道那是什么东西,关键是怎么遍历的问题.
比较简单的方法,参考String的split方法, 把那些数字拼成一个StringBuilder,去正则匹配1 ,然后进行计数就完了.
public class FindOne
{
public static void main(String[] args)
{
System.out.println(count(13));
} public static int count(int limit)
{
int count = 0;
for (int i = 0; i <= limit; i++)
{
count = count + countOne(i);
}
return count;
} public static int countOne(int n)
{
int count = 0;
if (n == 1)
{
count++;
} else
{
if (n % 10 == 1)
{
count = count + 1 + countOne((int) n / 10);
} else
{
count = count + countOne((int) n / 10);
}
}
return count;
}
}
{
public static void main(String[] args)
{
System.out.println(count(13));
} public static int count(int limit)
{
int count = 0;
for (int i = 0; i <= limit; i++)
{
count = count + countOne(i);
}
return count;
} public static int countOne(int n)
{
int count = 0;
if(n==0)
{
return 0;
}
if (n == 1)
{
return 1;
} else
{
if (n % 10 == 1)
{
count = count + 1 + countOne((int) n / 10);
} else
{
count = count + countOne((int) n / 10);
}
}
return count;
}
}
#include <math.h>using namespace std;long calLength(long n);
long countOnes(long n);long main()
{
long counter = 0;
long num;
cin >> num;
long length = calLength(num);
long base = 1;
for (long i = 0; i < length - 1; i ++)
{
base *= 10;
}
cout << "Base = : " << base << endl;
while (num > 0)
{
long tmp = num;
long btmp = base;
long one = 0; if (num / base == 0)
{
base /= 10;
} while ((one = tmp / btmp) != 1 && tmp > 10)
{
tmp %= btmp;
btmp /= 10;
} if (tmp < 10 && tmp >= 1)
{
counter ++;
num /= 10;
num *= 10;
num --;
continue;
} while (tmp >= 10 && tmp / btmp == 1)
{
counter += countOnes(num);
num --;
tmp --;
}
}
cout << counter << endl;
return 0;
}long calLength(long n)
{
long length = 0;
while (n)
{
n /= 10;
length ++;
}
cout << "Length = : " << length << endl;
return length;
}long countOnes(long n)
{
long counter = 0;
while (n)
{
if (n % 10 == 1)
counter ++;
n /= 10;
}
return counter;
}这个可以不
可以更方便解决
源码:
int num = 88,saveNum = 1,countNum = 0;
while(num!=0)
{
num/=10;
countNum +=(num+1)*saveNum;
saveNum*=10;
}
System.out.println(countNum);
编码思路:
****************************************
根据重复的数量级进行计算
对2238验证
8重复的是个位上的数量级 所以不变化
3重复的是十位上的数量级 所以每十个变换一次
2重复的是百位上的数量级 所以每百个变化一次
2重复的是千位上的数量级 所以每千个变化一次--个位【从十位往上算】
对于个位上的数量级 重复次数是个位除外 前n位的去零数
8 重复223+1次 所以有224*1--十位【从百位向上算】
3 重复22+1次 所以有23*10--百位【从千位本身向上算】
2 重复2+1次 所以有3*100--千位【从万位本身向上算】
2 重复1次 所以有1*1000
*******************
88验证
(8+1)*1 + 1*10
=19
*******************
295验证
(29+1)*1 + (2+1)*10 + (1)*100
=30+30+100
=160
*******************
322验证
(32+1)*1 + (3+1)*10 + (1)*100
=33+40+100
=173
*******************
999验证
(99+1)*1 + (9+1)*10 + (1)*100
=100+100+100
=300
224验证
(22+1)*1 + (2+1)*10 + (1)*100
=23+30+100
=153
100验证
(10+1)*1 + (1+1)*10 + (1)*100
=11+20+100
=131
bug:对于0 需要判读比如100
希望读懂思路以后 自己加上
对于详细思路可以加群
一起讨论:5307397
如有疏漏望指点
嗯 是的 有的地方会有bug 所以请大家研究下我的方法可行不
就你理我了 谢谢 wuuw
count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
}
if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
count += org % pow;
} else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
public static void main(String[] args) {
int n = 1010;
int result = 0;
int i = 1;
boolean flag = true;
if (n > 0) {
while (i < n + 1) {
String text = new Integer(i).toString();
if (text.indexOf("1") != -1) {
result++;
System.out.print(text + " ");
}
if (flag) {
i += 9;
flag = false;
} else {
i += 1;
flag = true;
}
}
}
System.out.println("\n共出现了:" + result);
}
}
#include <stdio.h>
#include <stdlib.h>int main(int argc, char *argv[])
{
if (2 != argc) {printf("usage:[%s] num\n", argv[0]); return -1;};
int num = abs(atoi(argv[1]));
int count = 0;
while (10 <= num)
{
int bits = 0, numtmp = num, curint = 1;;
while(1)
{
curint *= 10;
++bits;
if (10 >(numtmp = numtmp/10))
break;
}
if (numtmp > 1)
count += curint;
else
count += ((num%curint) + 1);
count += bits*((curint/10)*(num/curint));
num = num%curint;
}
if (num >= 1)
++count;
printf("%d\n", count);
return 0;
}
对于abcd这个数
公式:(abc+1)*1+(ab+1)*10+(a+1)*100+(1)*1000
依次类推。
对应:2234
(223+1)*1+(22+1)*10+(2+1)*100+(1)*1000
=224+230+300+1000
=1754
编程思路:
按照个位、十位、百位、千位……计算首先个位:例如88在下面表中可以看到,
88一直竖着向上 会有8+1个1(8来自十位上的数,8 7 6 ... ...)
之后十位:十位上,要看88 这个数没有百位。因为没有百位。
所以是(0+1)*10
88验证
(8+1)*1 + 1*10
=19
*******************
295验证
(29+1)*1 + (2+1)*10 + (1)*100
=30+30+100
=160
*******************
322验证
(32+1)*1 + (3+1)*10 + (1)*100
=33+40+100
=173
对应理解数字表:
01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120
121 122 123 124 125 126 127 128 129 130
131 132 133 134 135 136 137 138 139 140
141 142 143 144 145 146 147 148 149 150
151 152 153 154 155 156 157 158 159 160
161 162 163 164 165 166 167 168 169 170
181 182 183 184 185 186 187 188 189 190
191 192 193 194 195 196 197 198 199 200
201 202 203 204 205 206 207 208 209 210
211 212 213 214 215 216 217 218 219 220
221 222 223 224 225 226 227 228 229 230
1.如果最高位大于1,那当最高位为1的时候后面的数每一位有10中可能,一共就有3位,也就是1000个1
2.如果最高位等于1,那就是这个数除以1000的余数然后加自身的1,比如1001,那就是1+1=2,1011那就是11+1=12
这是最高位的情况,同样,当低位为1的时候算组合,由于最高位有限制,所以不可能有10种,所以低位为1的时候的组合数量为最高位的值*其他位的可能,2000的话次高位为1的时候就有2*10*10共两百种可能,其他的为以此类推,然后递归下去就得到答案了算法可能有很多,我的可能是其中一种,这里写了个一定能算出正确答案的傻瓜式代码供大家测试,申请的内存有限,不要让数值太大,懒得改了#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{
if (2 != argc) {printf("usage:[%s] num\n", argv[0]); return -1;};
int num = abs(atoi(argv[1]));
char *buff = malloc(1000000);
memset(buff, 0, 1000000);
char *guard = buff;
int i = 0;
for (; i<=num; ++i)
{
guard += sprintf(guard, "%d", i);
}
int count = 0;
for (guard=buff; '\0'!=*guard; ++guard)
{
if ('1' == *guard) ++count;
}
printf("%d\n", count);
return 0;
}
public class XiaoFuNumberGetOne { /**
* @param args
*
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int num = 11113,saveNum = 1,countNum = 0,lastNum=0,numCopy = num,oneCl = 1;
while(num!=0)
{
lastNum = num%10;
//System.out.println(lastNum);
num/=10; if(lastNum == 0){
countNum +=(num)*saveNum;
}else if(lastNum == 1){
countNum += num * saveNum + numCopy%(oneCl) + 1;
}else{
countNum +=(num+1)*saveNum;
}
oneCl*=10;
saveNum*=10;
}
System.out.println(countNum); }}
for ( int num = 0; num <= setting_num; num++ )
{
string str = int2string( num );
for ( int i = 0; i < str.length(); i++ )
{
int index = (int)(str[i]-'0');
totals[index]++;
}
}