以下代碼均是通過挑戰的,可能有更好方式實現或是思路,容有時間再作考慮,請不吝指正賜教,在此多謝了。
題目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