出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数;
分析:
- 从左向右处理string表示的数字;当前数字长度为n,判断最左边一位数字字符;
- 如果是0,则直接递归下一位;
- 如果是1,则计数有两个来源,一个是n位数数字(实际就是除去最高位之后的数字大小,加上1,当其余位全部为0的时候),另一个是n-1,n-2,……,1位数字,使用SpecialPower可以计算;
- 如果是其他数字,则计数有两个来源,一个是n,n-1,n-2,……,1位数字,使用SpecialPower可以计算,另一个是去除最高位之后的数字大小;
解题:
1 int NonRecursiveStrInt(char *target) {
2 int sum=0;
3 char *index=target;
4
5 while(*index != ‘\0‘) {
6 sum*=10;
7 sum+=*index-‘0‘;
8 index++;
9 }
10
11 return sum;
12 }
13
14 int SpecialPower(int n) {
15 int sum=0;
16 int product;
17 for(int i=0;i<n;i++) {
18 product=1;
19 for(int j=0;j<i;j++) {
20 product=product*10;
21 }
22 sum+=product;
23 }
24 return sum;
25 }
26
27 int count1Decimal2(char *decimal,int n) {
28 if(*decimal == ‘\0‘) return 0;
29 if(*decimal == ‘0‘) return count1Decimal2(++decimal,n-1);
30 if(*decimal == ‘1‘)
31 return NonRecursiveStrInt(++decimal) + 1 + SpecialPower(n-1);
32 return SpecialPower(n) + count1Decimal2(++decimal,n-1);
33 }
34
35 int main() {
36 char *decimal="16";
37 printf("\n%d\n",count1Decimal2(decimal,2));
38 return 0;
39 }
出题:输入一个正整数N,求所有和为N的连续正整数序列
分析:
- 橡皮筋解法,left和right为两端,当和小于N的时候右移right,当和大于N的时候左移left;
- 另外还有求等差数列和解法(2N的分解因子):a+(a+1)+……+(a+k)=N,则有a(k+1)+(k+1)k/2=N,则有(k+2a)(k+1)=2N,a和k需为整数,简单枚举即可;
解题:
1 int getSum(int start, int end) {
2 int sum=0;
3 for(int i=start;i<=end;i++) {
4 sum+=i;
5 }
6 return sum;
7 }
8 /**
9 * left表示序列开始,right表示序列结束,
10 * 初始化left为1,right为2
11 * 每当找到一个序列之后,需要重新初始化left和right
12 * 连续和至少两个数,所以left的最大值不能大于(n+1)/2
13 * 当和小于n则增大left表示加入数字
14 * 当和大于n则增大right表示减去数字
15 * */
16 void SucceSum(int n) {
17 if(n<=2) {
18 printf("\nn is less than 2\n");
19 return;
20 }
21 int left=1;
22 int right=2;
23
24 int mark=(n+1)/2;
25 int temp;
26 while(left<mark) {
27 temp=getSum(left, right);
28 if(n < temp) {
29 left++;
30 } else if(n > temp) {
31 right++;
32 } else {
33 printf("new sequence: \n");
34 for(int i=left;i<=right;i++) {
35 printf("%d, ",i);
36 }
37 printf("\n");
38 left++;
39 right=left+1;
40 }
41 }
42 }
时间: 2024-10-28 04:55:46