关于一些挑战题目

     以下代码均是通过挑战的,可能有更好方式实现或是思路,容有时间再作考虑,请不吝指正赐教,在此多谢了。

题目1

有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。 我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。 可以进行的操作是: 把一个容器灌满; 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸); 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。     问是否能够通过有限次操作,使得水缸最后恰好有C升水。 输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000 输出:0或1,表示能否达到要求。

 

解:

      c=i*a+j*b+m*(a+b)+n*(a-b)  i,jm,n属于整数。gcd(a,b)表示a和b 最大公约数。

code:

public static boolean can(int a,int b,int c){
	    boolean flag=false;
		int gcd_1=getGCD(a,b);

	    if(c%gcd_1==0||c%(2*gcd_1)==0){
	    	flag=true;
	    }else{
	    	if(Math.abs(a-b)!=0){
	    		if(c%Math.abs(a-b)%a==0||c%Math.abs(a-b)%b==0){
		    		flag=true;
		    	}
	    	}
	    	
	    	if(c%(a+b)%a==0||c%(a+b)%b==0){
	    		flag=true;
	    	}
	    }	
		return flag;
	}
	
	/**
	 * 取最大公约数
	 * @param a
	 * @param b
	 * @return
	 */
	public static int getGCD(int a,int b){
		if(b==0){
			return a;
		}
		return getGCD(b,a%b);
		
	}
	
	public static void main(String[] args){
		
		
		int[] c=new int[26];
		System.out.println(getGCD(1234567,7654321));
		boolean f=can(12,76,9999999);
		System.out.println(f);
	}


【2016-09-23  重写  公约数算法】

 

	public static int gdc(int a,int b){
		while(b!=0){
			int temp = b;
			b = a % b;
			a = temp;
		}
		return a;
	}




题目2

 给定一个包含1-n的数列,我们通过交换任意两个元素给数列重新排序。求最少需要多少次交换,能把数组排成按1-n递增的顺序,其中,数组长度不超过100。 例如: 原数组是3,2,1, 我们只需要交换1和3就行了,交换次数为1,所以输出1。 原数组是2,3,1,我们需要交换2和1,变成1,3,2,再交换3和2,变为1,2,3,总共需要的交换次数为2,所以输出2。

 

解:

   插入排序的思想,遍历a数组,取元素i与 i+i,i+2...(a.length-1)的元素比较交换。下标1的位置要找到元素中最小的元素,下标2的找次小的元素交换,以此类推。

code:

import java.util.Arrays;
public class ArrSortCnt {
	
	public static int run(int[] a){
		   System.out.println("排序前数组:"+Arrays.toString(a));
		   
	       int count=0;
	       for(int i=0;i<a.length;i++){
	           int temp=a[i];
	           int j=i+1;
	           int swapIndex=i;
	           while(j<a.length){
	               if(temp>a[j]){
	                   temp=a[j];
	                   swapIndex=j;
	               }
	               j++;
	           }
	          
	           if(temp!=a[i]){
	        	  count++;
	           }
	           
	           a[swapIndex]=a[i];
	           a[i]=temp;

	       }   
	       
	       System.out.println("排序后数组:"+Arrays.toString(a));
	       return count;
	       
	   } 
	
	public static void main(String[] args){
		int a[] = {10,2,8,7,6,5,4,3,9,1};
		int cnt=run(a);
		System.out.println(cnt);
		
		
	}

}


 

题目3:

我们要给每个字母配一个1-26之间的整数,具体怎么分配由你决定,但不同字母的完美度不同, 而一个字符串的完美度等于它里面所有字母的完美度之和,且不在乎字母大小写,也就是说字母F和f的完美度是一样的。 现在给定一个字符串,输出它的最大可能的完美度。 例如:dad,你可以将26分配给d,25分配给a,这样整个字符串最大可能的完美度为77。

 

解:

   计数排序的思想,记录数组a中的元素个数,元素最大的*26,次之*25,以此类推。

 code:

import java.util.Arrays;
public class PerfectChar {
	
	 public static int perfect(String s){
	     s=s.toLowerCase();
	     char[] chs=s.toCharArray();
	     int[] cnts=new int[chs.length];
	     Arrays.fill(cnts,1);
	     
	     for(int i=0;i<chs.length;i++){
	        if(cnts[i]==0){
	            continue;
	        }
	        for(int j=i+1;j<chs.length;j++){
	            if(chs[j]==chs[i]){
	                cnts[i]++;
	                cnts[j]=0;
	            }
	        }
	     }
	     Arrays.sort(cnts);
	     
	     int total=0;
	     int maxVal=26;
	     for(int i=cnts.length-1;i>=0;i--){
	         total+=maxVal*cnts[i];
	         maxVal--;
	     }

	     return total;
	 }
	 
	 public static void main(String[] args){
		 String a="abcc";
		 int total=perfect(a);
		 System.out.println(total);
	 }
}


以下代码未通过挑战,未发现问题,先贴上来,有时间再作修改。

题目4:

回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。 输入:非空仅由小写字母组成的字符串,长度不超过100; 输出:能组成的所有回文串的个数(因为结果可能非常大,输出对1000000007取余数的结果)。 例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab)

 

【2017-01-05 修改】 

分析:

   

CODE : 

/**
	 * 回文字符总数
	 * @param str 仅由小写字母组成
	 * @return
	 */
	public int getPalindromicCount(String str){
		int[] c = new int[26];
		char[] chs = str.toCharArray();
		for(int i =0;i<chs.length;i++){
			c[chs[i]-97]++;
		}
		
		int result = 0;
        if(!isNotPalindromic(c)){
        	result = calculate(c,chs.length);
		}
        
        System.out.println("结果:"+result);
		return result;
	}
	
	/**
	 * 计算排列A(m+n+k,m+n+k)/(A(m,m)*A(n,n)*A(k,k))
	 * @return
	 */
	public int calculate(int[] c,int strLen){
        double t  = factorial(strLen/2);
        double m  = 1;
        for(int i =0;i<c.length;i++){
        	if( c[i]!=0){
        		int n = c[i]/2;
        		m *= factorial(n);
        	}
		}
		
		int result = (int)(t/m%1000000007);
		return result;
	}
	/**
	 * 阶乘
	 * @param n
	 * @return
	 */
	public double factorial(int n){
		if(n<=0){
			return 1;
		}
		return factorial(n-1)*n;
	}
	
	/**
	 * 是否可以构成回文字符
	 * <p>
	 *    统计的字母个数,如果奇数位的个数>1,则不能构成回文。
	 *    比如 字符aaabbb(3*a3*b),奇数位>1,所以不能构成回文。
	 * </p>
	 * @param c
	 * @return
	 */
	public boolean isNotPalindromic(int[] c){
		int odd = 0;
		for(int i =0;i<c.length;i++){
			if ((c[i]&1) == 1){
				odd++;
			}      	
		}
		return (odd>1);
	}


结果:

输入:aaabbb
返回: 0

输入:aabb
返回:2

输入: aab
返回: 1

输入: a
返回: 1

输入: aaaa
返回: 1







   









 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值