急:求一个算法,跪求!!

鏊鏊 2015-10-31 10:04:42
加精
4个数。
1<=n1,n1<n2,n2<1000000000,0<=a<=9,0<=b<=9,a!=b
求在n1--n2之间不含a,但是含有b的数字有到多少个?要求用算法,10秒能出来= =
当n1=1,n2=999999999时要求10秒算出结果。= =

...全文
4200 57 打赏 收藏 转发到动态 举报
写回复
用AI写文章
57 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33440254 2017-02-07
  • 打赏
  • 举报
回复
9*9*9*9*9*9*9*9*9*9-8*8*8*8*8*8*8*8*8 9个9相乘(不包含a)减去8个8相乘 (不包含a且不包含b) 就是0到10亿之间的不包含(0-9)某一个数字而包含(0-9)另一个数字的个数
LittleFish_yozo 2016-10-21
  • 打赏
  • 举报
回复
一道不错的排列组合数学竞赛题
qq_34092472 2016-04-28
  • 打赏
  • 举报
回复
先假设a=9;b=8没有a的情况就是将数字转换成9进制数(数字代指要求的最大范围),转换后数字就是不包含9的数的个数;这个数字中包含不含8的部分和含8的部分,不含8的数字个数就是和之前一样将数字(数字代指要求的最大范围)转换成8进制数转换后数字就是不包含9和8两个数字的的数的个数;两者相减就是含8而不含9的个数; 以上是一个循环,再将a与b的几种情况循环(注:若a与b恰好等于0,1可直接将数字要求的最大范围的各个位上的数字转换成离其最小的个位数,例1000可以九进制可以看成21111八进制可看成32222,所以a,b分别是多少对结果无影响) 只是个人想法,如果不对请见谅,指正!!
qq_34092472 2016-04-27
  • 打赏
  • 举报
回复
把10进制数转换9进制数!试试
liuyangyangNO1 2016-04-25
  • 打赏
  • 举报
回复
import java.util.Scanner;
/**
 * 4个数。
 * 1<=n1,n1<n2,n2<1000000000,0<=a<=9,0<=b<=9,a!=b
 * 求在n1--n2之间不含a,但是含有b的数字有到多少个?要求用算法,10秒能出来= =
 * 当n1=1,n2=999999999时要求10秒算出结果。
 * @author Administrator
 *
 */
public class Test3 {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入n1(0<=n1<1000000000):");		
		int n1 = sc.nextInt(); 
//		String n1Num = ""+n1;
		int n1N = (""+n1).length();
		System.out.println("请输入n2(n1<n2<1000000000):");
		int n2 = sc.nextInt();
//		String n2Num = ""+n2;
		int n2N = (""+n2).length();
		System.out.println("请输入a和b,0<=a<=9,0<=b<=9,且a不等于b,a与b用逗号隔开:");	
		String ab = sc.next();
		int a = Integer.valueOf((ab.split(",")[0]));
		int b = Integer.valueOf((ab.split(",")[1]));
		sc.close();
		int count = 0;
		if(n1N==n2N){
			count = front(n1,a,b)-front(n2,a,b);
		}
		else{
			count = front(n1,a,b);
			for(int i=n1N+1;i<=n2N;i++){
				count = count + exe(i,a,b);
			}
			count = count - front(n2,a,b);
		}
		System.out.println(count);
//		System.out.println(c(5,3));
//		System.out.println(nFactorial(4));
//		System.out.println(exe(2,a,b));
//		System.out.println(power(2,3));
//		System.out.println(add(false,3,2,4,5));
//		System.out.println(front(23,4,5));
	}
	/**
	 * 计算n位数中含b,不含a的数的个数
	 * @param n:数的位数
	 * @param a:不含的数字
	 * @param b:必须含的数字
	 * @return
	 */
	public static int exe(int n,int a,int b){
		int count=0;
		if(b==0){
			if(n==1){
				count=1;
			}
			else{
				for(int i=1;i<n;i++){
					count=count+power(8,n-i)*c((n-1),i);
				}
			}			
		}
		else if(a==0){
			for(int i=1;i<=n;i++){
				count=count+power(8,n-i)*c(n,i);
			}
		}
		else{
			for(int i=1;i<n;i++){
				count=count+7*power(8,n-i-1)*c(n-1,i);
			}
			for(int i=0;i<n;i++){
				if(i==0){
					count=count+power(8,n-1);
				}
				else{
					count=count+power(8,n-1-i)*c(n-1,i);
				}				
			}
		}
		return count;
	}
	/**
	 * a的n次方
	 * @param a
	 * @param n
	 * @return
	 */
	public static int power(int a,int n){
		int res = 1;
		while(n>0){
			res = res * a;
			n--;
		}
		return res;
	}
	/**
	 * 排列组合中c(n,m)
	 * @param n
	 * @param m
	 * @return
	 */
	public static int c(int n,int m){
		int res = 1;
		int mm = m;
		for (; mm > 0; mm--)
        {
            res *= n;
            n--;
        }
		return (res / nFactorial(m));
	}
	/**
	 * n的阶乘
	 * @param n
	 * @return
	 */
	public static int nFactorial(int n){
		int res = 1;
		for (; n > 0; n--)
        {
            res *= n;
        }
		return res;
	}
	/**
	 * 
	 * @param n:数字
	 * @param N:n所在的位(即个位、十位、百位等)
	 * @return
	 */
	public static int add(boolean TorF,int n,int N,int a,int b){
		int count = 0;
		for(int i=n;i<10;i++){
			if(i==a){
				continue;
			}
			else{
				if(TorF){
					if (N == 1) {
						count++;
						continue;
					} 
					else {
						count = count + power(9,N-1);
					}
				}
				else{
					if (N == 1) {
						if(i==b){
							count ++;
						}						
					}
					else{
						if(i==b){
							count = count + power(9,N-1);
						}
						else{
							for(int j=1;j<N;j++){
								count = count + c(N-1,j)*power(8,N-1-j);
							}
						}
					}
				}
			}
		}		
		return count;
	}
	/**
	 * 计算n1到相同位数最大值之间满足条件的数的个数(如123~999满足条件的数的个数)
	 * @param n1
	 * @param a
	 * @param b
	 * @return
	 */
	public static int front(int n1,int a,int b){
		int count = 0;
		String start = ""+n1;
		int N = start.length();
		int[] startnum = new int[N];
		for(int i=0;i<N;i++){
			startnum[i] =Integer.parseInt(String.valueOf(start.charAt(N-1-i)));
		}
		int aa = -1;
		for(int i=N-1; i>0; i--){
			if(startnum[i]==a){
				aa = i;
				break;
			}				
		}
		if(aa!=-1){
			if(aa==N-1){
				if(startnum[aa]==9){
					count = 0;
				}
				else{
					count = count + add(false,startnum[aa]+1,aa+1,a,b);
				}				
			}
			else{
				boolean TorF = false;
				for(int i=aa+1;i<N;i++){
					if(startnum[i]==b){
						TorF = true;
						break;
					}
				}
				if(startnum[aa]==9){
					count = 0;
				}
				else{
					count = count + add(TorF,startnum[aa]+1,aa+1,a,b);
				}	
				for(int i=aa+1;i<N;i++){
					if(startnum[i]==9){
						continue;
					}
					else{
						if(i==N-1){
							count = count + add(false,startnum[i]+1,i+1,a,b);
						}
						else{
							boolean TORF = false;
							for(int j=i+1;j<N;j++){
								if(startnum[j]==b){
									TORF = true;
									break;
								}								
							}
							count = count + add(TORF,startnum[i]+1,i+1,a,b);
						}
					}
				}
			}			
		}
		else{
			for(int i=0;i<N;i++){
				if(startnum[i]==9){
					continue;
				}
				if(i==N-1){
					count = count + add(false,startnum[i]+1,i+1,a,b);
					break;
				}
				else{
					boolean TorF = false;
					for(int j=i+1;j<N;j++){
						if(startnum[j]==b){
							TorF = true;
							break;
						}
					}
					count = count + add(TorF,startnum[i]+1,i+1,a,b);
				}
				
			}
		}
		return count;
	}
}
个人测试了几组数据,感觉还可以,不知道能满足楼主的要求不。。。????
NothingSerious2811 2016-03-24
  • 打赏
  • 举报
回复
我会,这问题解决了没
MaXiaoqiang212 2016-03-23
  • 打赏
  • 举报
回复
我已瞎。。。
qq_32730311 2015-11-12
  • 打赏
  • 举报
回复
1<=n1 n1<n2<999999999 直接说个1<n<999999999么好咯 在n之间的数
qq_32730311 2015-11-12
  • 打赏
  • 举报
回复
lone_cheerUp 2015-11-11
  • 打赏
  • 举报
回复
你这里的包含意思是n1=1, n2=9999, a = 4, b = 5。 14 就是包含了a,15就是包含了b但不包含a,145就是包含a也包含b,是这个意思吗?
tufu3261 2015-11-11
  • 打赏
  • 举报
回复
传说中的。。。。
鏊鏊 2015-11-09
  • 打赏
  • 举报
回复
引用 33 楼 af463419014 的回复:

	private static int a=3,b=6;
	public static void main(String[] args) throws JsonProcessingException {
		int ans1=getc(new int[]{2,2,8,6});
		int ans2=getc(new int[]{2,2,4,2,6});
		System.out.println(ans2-ans1);
	}
	
	private static int getc(int[] ni) throws JsonProcessingException{
		int[] f=new int[9];
		int[] g=new int[9];
		f[0]=0;
		g[0]=0;
		f[1]=1;
		g[1]=9;
		for(int i=2;i<9;i++){
			f[i]=f[i-1]*8+g[i-1];
			g[i]=g[i-1]*9;
		}
		int ans=0;
		for(int i=ni.length-1,type=0;i>=0;i--){
			int j=ni[ni.length-i-1];
			int tmp=j;
			if(a<j){
				tmp--;
			}
			if(type==0){
				if(b<j){
					ans+=(tmp-1)*f[i]+g[i];
				}else{
					ans+=tmp*f[i];
				}
				if(j==b){
					type=1;
				}
			}else{
				ans+=tmp*g[i];
			}
			

			if(j==a){
				break;
			}
			
		}
		System.out.println(ans);
		return ans;
	}
//----------------------------后面这个是验证程序,效率低但是10万以内还是可以出结果

	public static void main(String[] args) throws JsonProcessingException {
		int n=22426;
		int m=2286;
		int a=3,b=6;
		int ans=0;
		for(int i=m;i<n;i++){
			int[] ni=new int[10];
			int tmp=i,j=0;
			while(tmp!=0){
				ni[j++]=tmp%10;
				tmp/=10;
			}
			
			int pd=0;
			for(j=0;j<ni.length;j++){
				if(ni[j]==a){
					pd=2;
				}
				if(pd==0){
					if(ni[j]==b){
						pd=1;
					}
				}
			}
			if(pd==1){
				ans++;
				System.out.println(ans+":"+i);
			}
		}
		System.out.println("ans:"+ans);
		
	}
谢谢了.这个有用,就是总会差一个..再就是a =0时无法计算
StunningBoy 2015-11-06
  • 打赏
  • 举报
回复
引用 31 楼 liacw1017 的回复:
第一种先考虑,a,b都不等于0的情况 , a或者b等于0的情况要单独考虑 从个位数来看,不含a,但是含有a的数字只有一个, n1 = 1; 从两位数来看,有三种清楚, b在十位,各位数不是a,也不是b,共有8种情况 b在个位,十位上不是a,也不是b,也不是0,共7种 b在个位,也在十位 共1种情况 n2 = 8+7+1 = 16 三位数来看,有C31 + C32 +C33 = 3 + 3 + 1 = 7 种情况 x = 3 C31 8^(x-2)*7*(x-1)+8^(x-1) = 8*7*2 + 8*8 = 176 C32 8 + 8 + 7 = 23 2*8 + 1*1*7 = 23 C33 1 n3 = 176 + 23 +1 = 200 四位数来看有 C41 + C42 + C43 + C44 = 4 + 6 + 4 + 1 = 15种情况 x = 4 C41 1856 C42 C(x-1)1*8^(x-2) + C(x-2)1*8^(x-3)*7 + C(x-3)1*8^(x-3)*7 = 3*8*8 + 2*8*7 + 1*8*7 = 192 + 112 + 56 = 360 C43 7+8+8+8 = 31 C44 1 n4 = 2248 后面五位数,六位数等情况其实也可以找到类似的算法,就不一一分析了
貌似这分析是对的。
blueice2004 2015-11-06
  • 打赏
  • 举报
回复
2.a=0,b!=0 公式:8^0*(9^m-1)+8^1*(9^(m-1)-1)+8^2*(9^(m-2)-1)+...+8^m*(9^0-1)
blueice2004 2015-11-06
  • 打赏
  • 举报
回复
分三种情况: 设m=N-1,N是数字位数,题中N=9 1. a != 0, b !=0 ,这种情况最简单 公式 (8^0)*(9^(m))+(8^1)*(9^(m-1))+(8^2)*(9^(m-2))+...+(8^m)*(9^(m-m))
blueice2004 2015-11-06
  • 打赏
  • 举报
回复
关于这个问题,我用了2个多小时,用数学方法解出来了,详细解法如下
wlj2zyy 2015-11-06
  • 打赏
  • 举报
回复
xuofeng 2015-11-06
  • 打赏
  • 举报
回复
完全没看懂?????????
gw6328 2015-11-06
  • 打赏
  • 举报
回复
引用 37 楼 mflzwz 的回复:
[quote=引用 16 楼 Poopaye的回复:][quote=引用 15 楼 jinfengyiye 的回复:] [quote=引用 10 楼 shingoscar 的回复:] [quote=引用 楼主 wangvsin 的回复:] 4个数。 1<=n1,n1<n2,n2<1000000000,0<=a<=9,0<=b<=9,a!=b 求在n1--n2之间不含a,但是含有b的数字有到多少个?要求用算法,10秒能出来= = 当n1=1,n2=999999999时要求10秒算出结果。= =
a==0的时候有8个数 a!=0的时候有7个数 难道不是这样吗? 难道不是这样吗? 难道不是这样吗?[/quote] a=0 b 有2,3,....8 共7种值 a=1 b 有 3......8 a=2 .. a=4 了可能有1也 最后b 就是有1~8 共8种值啊。 我的答案也是这种,可能是楼主描述错了。如果按题上的好多种值就是1~8 ,[/quote] 对的,我就这么想的[/quote] 谁告诉你们n1到n2的值域是0到10..........题目看清楚啊[/quote] 谁又告诉你这里n1到n2是0~10?你也再看一下上面的情况。我们说的是b值的情况,和n没有关系。b为6 ,n1为5,n2为tmd100~1000都没有关系。b值的情况。你个b货。
码农7号- 2015-11-05
  • 打赏
  • 举报
回复
排列组合的问题了。不难
加载更多回复(34)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧