UESTC--1264

人民币的构造

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit  Status

我们都知道人民币的面值是 12510 ,为什么是这个数值呢,我们分析了下发现,从 110 的每个数字都可以由每种面值选出至多一张通过加法和减法(找钱)来构成,(比如: 1+2=351=45+1=65+2=71+2+5=8101=9

但是实际上,我们只需要 127 三种面值就可以组成 110 的每一个数字了

1+2=3712=472=571=67+1=87+2=97+1+2=10

那么现在问题来了,给一个数 n ,请问最少需要多少种不同的面值就可以构成从 1n 的所有数字,注意在构成每一个数字时同种面值不能超过 1 张。

Input

一个数字 n (1<= n <=100000)

Output

一个数字,代表最少需要多少种不同的面值可以构成从 1n 的所有数字。

Sample input and output

Sample Input Sample Output
10
3

Source

第七届ACM趣味程序设计竞赛第三场(正式赛)

解体思路:用公式x>log10(2*n+1)/log10(3)然而WA了的同学注意了,这里在比较整数与小数的大小时注意精度问题,不然会WA到底。

代码如下:
#include<stdio.h>
#include<cmath>
int main(){
	int n;
    double s,y;
    y=log10(3.0);
    while(scanf("%d",&n)!=EOF){
    	s=log10(2*n+1.0)/y;
    	int x;
    	x=s;
    	if(s-x>1e-8)x++;
    	printf("%d\n",x);
    }
	return 0;
}

第二种方法:在网上找了人家用数论做的分析,感觉思路非常巧妙;假设当前可以取道[1,K],再增加一个数A,那么此时可以取道的范围是[1,K]U[ A-K,A+K],A是不固定的,为了要尽量时右端点扩大,所取的范围最大,那么此时A-K=K+1,右端点=3*K+1;

代码如下:
#include<stdio.h>
int a[15];
int main(){
	int n,i;
	a[1]=1;
	for(i=2;i<=12;i++){
		a[i]=3*a[i-1]+1;
	}
	while(scanf("%d",&n)!=EOF){
		for(i=1;i<=12;i++){
			if(n<=a[i]){
				printf("%d\n",i);
				break;
			}
		}
	}
	return 0;
}


你可能感兴趣的:(UESTC--1264)