1. 程式人生 > >華為OJ題解(中級)

華為OJ題解(中級)

密碼驗證合格程式

import java.util.Scanner;

public class Main {
	//子串出現次數(避免交叉)
	private static int countOf(String str,String subStr){
		if(str.indexOf(subStr)==-1){
			return 0;
		}else{
			int indexOf=str.indexOf(subStr);
			return 1+countOf(str.substring(indexOf+subStr.length()),subStr);
		}
	}
	//判定所以子串(長度大於2)是否有重複
	private static boolean isDuplicate(String str){
		if(str.length()<=2) return false;
		for(int i=0;i<=str.length()-3;i++){
			for(int j=i+3;j<=str.length();j++){
				if(j-i>str.length()/2)break;//長度超過一半的子串忽略
				if(countOf(str,str.substring(i,j))>=2){
					return true;
				}
			}
		} 
		return false;
	}
	//統計字元種數
	private static int categoryNum(String str){
		int number=0,bigger=0,little=0,other=0;//統計字元
		for(int i=0;i<str.length();i++){
			char c=str.charAt(i);
			if('0'<=c&&c<='9'){
				number=1;
			}else{
				if('A'<=c&&c<='Z'){
					bigger=1;
				}else{
					if('a'<=c&&c<='z'){
						little=1;
					}else{
						other=1;
					}
				}
			}  
		}
		return number+bigger+little+other; 
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);   
		while(in.hasNext()){
			String s=in.next();  
			if(s.length()>8&&categoryNum(s)>=3&&!isDuplicate(s)){
				System.out.println("OK");
			}else{
				System.out.println("NG");
			}
		} 
	}
}

汽水瓶

import java.util.Scanner;

public class Main {	 
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);   
		while(in.hasNext()){ 
			int num=in.nextInt();
			if(num==0)return;
			System.out.println(num/2);
		} 
	}
}

刪除字串中出現次數最少的字元

import java.util.Scanner;

public class Main {
	 
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);   
		String s=in.next();
		int[] counts=new int[128];
		for(int i=0;i<s.length();i++){//統計次數
			counts[s.charAt(i)]++;
		}
		int min=Integer.MAX_VALUE;
		for(int i=0;i<128;i++){//尋找最小次數
			if(counts[i]!=0){
				min=Math.min(min, counts[i]);
			}
		}
		StringBuilder builder=new StringBuilder();
		for(int i=0;i<s.length();i++){//計算結果
			if(counts[s.charAt(i)]!=min){
				builder.append(s.charAt(i));
			}
		}
		System.out.println(builder.toString());
	}
}

字串排序

 
import java.util.Scanner;

public class Main {
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);   
		String s=in.nextLine(); 
		StringBuilder builder=new StringBuilder();
		for(int i=0;i<s.length();i++){ 
			char c=s.charAt(i);
			if(('a'<=c&&c<='z')||('A'<=c&&c<='Z')){
				builder.append(c);
			}
		}
		char[] cs=builder.toString().toCharArray();//記錄所有字元
		for(int i=cs.length-1;i>0;i--){//冒泡,穩定(可以採用歸併排序)
			for(int j=0;j<i;j++){
				if(Character.toUpperCase(cs[j])>Character.toUpperCase(cs[j+1])){
					char t=cs[j];cs[j]=cs[j+1];cs[j+1]=t;
				}
			}
		}
		builder.setLength(0);//清空builder
		int index=0;
		for(int i=0;i<s.length();i++){//綜合得到結果
			char c=s.charAt(i);
			if(('a'<=c&&c<='z')||('A'<=c&&c<='Z')){
				builder.append(cs[index++]);
			}else{
				builder.append(c);
			}
		}
		System.out.println(builder.toString());
	}
}

查詢兄弟單詞

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
	//將字元轉換成排序後的標準形式
	private static boolean isBrother(String a,String b){
		if(a.length()!=b.length()) return false; 
		int[] countA=new int[26];
		int[] countB=new int[26];
		for(int i=0;i<a.length();i++){
			countA[a.charAt(i)-'a']++;
		}
		for(int i=0;i<b.length();i++){
			countB[b.charAt(i)-'a']++;
		}
		for(int i=0;i<26;i++){
			if(countA[i]!=countB[i])return false;
		}
		return true;
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);  
		ArrayList<String> words=new ArrayList<String>();
		int n=in.nextInt();
		for(int i=0;i<n;i++){
			words.add(in.next());
		}
		String find=in.next();
		int index=in.nextInt();
		ArrayList<String> brothers=new ArrayList<String>();
		HashMap<String,Boolean> findedBrother=new HashMap<String,Boolean>();//過濾重複兄弟
		for(String s:words){
			if(isBrother(s,find)&&!s.equals(find)&&!findedBrother.containsKey(s)){
				brothers.add(s);
				findedBrother.put(s, true);
			}
		}
		Collections.sort(brothers);//對兄弟字典排序
		System.out.println(brothers.size());
		System.out.println(brothers.get(index-1));
	}
}

[中級]單詞倒排

import java.util.ArrayList; 
import java.util.Scanner;

public class Main { 
	private static boolean isCharacter(char c){
		return ('a'<=c&&c<='z')||('A'<=c&&c<='Z')?true:false; 
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);    
		ArrayList<String> words=new ArrayList<String>();
		StringBuilder candidate=new StringBuilder();
		String s=in.nextLine();
		for(int i=0;i<s.length();i++){
			char c=s.charAt(i);
			if(isCharacter(c)){//字母加入
				candidate.append(c);
			}else{//遇到非字母
				if(candidate.length()!=0){//如果有單詞則新增
					words.add(candidate.toString());
					candidate.setLength(0);//重置
				}
			}
		}
		if(candidate.length()!=0){//末尾處理
			words.add(candidate.toString());
			candidate.setLength(0);
		}
		if(words.size()==0)return;
		for(int i=words.size()-1;i>=1;i--){
			System.out.print(words.get(i)+" ");
		}
		System.out.print(words.get(0));
	}
}

整數與IP地址間的轉換

import java.util.Scanner;

public class Main { 
	private static int ipToInt(String ip){
		String[] values=ip.split("\\.");
		int one=Integer.parseInt(values[0]);
		int two=Integer.parseInt(values[1]);
		int three=Integer.parseInt(values[2]);
		int four=Integer.parseInt(values[3]);
		return (one<<24)+(two<<16)+(three<<8)+four;
		
	}
	public static String intToIp(int value){
		StringBuilder builder=new StringBuilder();
		int one=(value&0xff000000)>>24;
		int two=(value&0x00ff0000)>>16;
		int three=(value&0x0000ff00)>>8;
		int four=(value&0x000000ff);
		builder.append(one).append('.').append(two).append('.')
		.append(three).append('.').append(four);
		return builder.toString(); 
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);     
		String ip=in.next();
		int value=in.nextInt();
		System.out.println(ipToInt(ip));
		System.out.println(intToIp(value));
	}
}

統計每個月兔子的總數

import java.util.Scanner;

public class Main {  
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);      
		int month=in.nextInt();  
		int age1=1,age2=0,age3=0;//分別代表各個年齡兔子個數
		for(int m=2;m<=month;m++){ 
			age3+=age2;//先計算age3
			int newCount=age3;//再計算新的age1
			age2=age1;
			age1=newCount;
		}
		System.out.print(age1+age2+age3); 
	}
}
當然,問題實質上是斐波那契數列,我們可以採用任何斐波那契數列的求解方法。

但是,你不一定能一眼看出問題的本質,還是得掌握基本求解思路。

求小球落地5次後所經歷的路程和第5次反彈的高度

import java.util.Scanner;

public class Main {  
	public static void main(String[] args){//畫圖輔助思路
		Scanner in = new Scanner(System.in);      
		double height=in.nextDouble(); //高度  
		double res=height;//路徑長度
		height/=2;
		for(int i=1;i<=4;i++){
			res+=height*2;
			height/=2;
		}
		System.out.println(res);
		System.out.println(height);
	}
}

迷宮問題

<pre name="code" class="java">import java.util.HashSet; 
import java.util.Scanner;
import java.util.Stack;

public class Main {  
	private static class Point{
		public int m;
		public int n;
		Point pre=null;//前驅座標
		public Point(int m,int n){
			this.m=m;
			this.n=n;
		}
		//重寫
		@Override
		public boolean equals(Object obj){
			Point comp=(Point)obj;
			if(this.m==comp.m&&this.n==comp.n){
				return true;
			}else{
				return false;
			}
		}
		@Override
		public int hashCode(){
			return m*1000+n;
		}
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);   
		int m=in.nextInt(),n=in.nextInt();
		int[][] a=new int[m][n];  
		for(int i=0;i<m;i++){
			for(int j=0;j<n;j++){
				a[i][j]=in.nextInt();
			} 
		}
		HashSet<Point> finds=new HashSet<Point>();//已經可達的點
		finds.add(new Point(0,0));//初始化
		Point end=new Point(m-1,n-1);
		while(!finds.contains(end)){//寬度優先遍歷
			HashSet<Point> newPoints=new HashSet<Point>(); //下一步可達的點 
			for(Point p:finds){ 
				if(p.m>0){//上
					Point t=new Point(p.m-1,p.n);
					if(!finds.contains(t)&&!newPoints.contains(t)&&a[t.m][t.n]==0){
						t.pre=p;
						newPoints.add(t); 
					}
				}
				if(p.m<m-1){//下
					Point t=new Point(p.m+1,p.n);
					if(!finds.contains(t)&&!newPoints.contains(t)&&a[t.m][t.n]==0){
						t.pre=p;
						newPoints.add(t); 
					}
					if(t.equals(end)){
						end=t;
						break;
					}
				}
				if(p.n>0){//左
					Point t=new Point(p.m,p.n-1);
					if(!finds.contains(t)&&!newPoints.contains(t)&&a[t.m][t.n]==0){
						t.pre=p;
						newPoints.add(t); 
					}
				}
				if(p.n<n-1){//右
					Point t=new Point(p.m,p.n+1);
					if(!finds.contains(t)&&!newPoints.contains(t)&&a[t.m][t.n]==0){
						t.pre=p;
						newPoints.add(t); 
					}
					if(t.equals(end)){
						end=t;
						break;
					}
				}
			} 
			for(Point np:newPoints){//加入新找到的點
				finds.add(np);
			} 
		}
		Stack<Point> stack=new Stack<Point>();//倒敘輸出
		Point p=end;
		while(p!=null){
			stack.push(p);
			p=p.pre;
		}
		while(!stack.isEmpty()){
			Point loc=stack.pop();
			System.out.println("("+loc.m+","+loc.n+")");
		} 
	}
}

Sudoku-java

import java.util.ArrayList;
import java.util.Scanner; 
public class Main{ 
	private static boolean solve(char[][] board,int index,ArrayList<ArrayList<Integer>> emptyLocations){  
	    if(index==emptyLocations.size()){  
	        return true;  
	    }  
	    ArrayList<Integer> location=emptyLocations.get(index);  
	    int row=location.get(0),col=location.get(1);  
	    for(char c='1';c<='9';c++){   
	        if(isValid(board,row,col,c)){  
	            board[row][col]=c;  
	            if(solve(board,index+1,emptyLocations)){  
	                return true;  
	            }else{  
	                board[row][col]='.';  
	            }  
	        }  
	    }  
	    return false;  
	}  
	public static boolean isValid(char[][] board,int row,int col,char c){  
	    //驗證行  
	    for(int i=0;i<9;i++){  
	        if(board[row][i]==c)  
	            return false;  
	    }  
	    //驗證列  
	    for(int i=0;i<9;i++){  
	        if(board[i][col]==c)  
	            return false;  
	    }  
	    //驗證3*3格子  
	    for(int i=(row/3)*3;i<(row/3)*3+3;i++){  
	        for(int j=(col/3)*3;j<(col/3)*3+3;j++){  
	            if(board[i][j]==c)  
	                return false;  
	        }  
	    }  
	    return true;  
	}  
	public static void solveSudoku(char[][] board) {  
	    ArrayList<ArrayList<Integer>> emptyLocations=  
	            new ArrayList<ArrayList<Integer>>();  
	    for(int row=0;row<9;row++){  
	        for(int col=0;col<9;col++){  
	            if(board[row][col]=='.'){  
	                ArrayList<Integer> location=new ArrayList<Integer>();  
	                location.add(row);location.add(col);  
	                emptyLocations.add(location);  
	            }  
	        }  
	    }  
	    solve(board,0,emptyLocations);  
	}  
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in); 
        char[][] board=new char[9][9];
        for(int i=0;i<9;i++){
        	for(int j=0;j<9;j++){
        		char c=(char) (in.nextInt()+'0');
        		if(c=='0'){
        			board[i][j]='.';
        		}else{
        			board[i][j]=c;
        		}
        	}
        }
        solveSudoku(board); 
        for(int i=0;i<9;i++){
        	for(int j=0;j<8;j++){ 
        		System.out.print(board[i][j]+" ");
        	}
        	System.out.print(board[i][8]);
        	System.out.println();
        }
    }
}

計算字串的距離(編輯距離)

分析 動態規劃演算法。 遞迴版本:
import java.util.Scanner; 

public class Main {   
    private static int distanceOf(String a,int endA,String b,int endB){
    	if(endA<endB){//保證a比b長
    		int t=endA;endA=endB;endB=t;
    		String ts=a;a=b;b=ts;
    	}
    	if(endB==-1)return endA+1;//如果較短的為空,返回較長的長度
    	if(a.charAt(endA)==b.charAt(endB)){//末尾相等
    		return distanceOf(a,endA-1,b,endB-1);
    	}else{
    		return 1+Math.min(distanceOf(a,endA-1,b,endB-1),distanceOf(a,endA-1,b,endB));
    	} 
	}
    
    public static void main(String[] args) {    
        Scanner in=new Scanner(System.in); 
        String a=in.next();
        String b=in.next();
        System.out.println(distanceOf(a,a.length()-1,b,b.length()-1));
    }  
}  
迭代版
import java.util.Scanner; 

public class Main {    
    public static void main(String[] args) {    
        Scanner in=new Scanner(System.in); 
        String a=in.next();
        String b=in.next(); 
        int m=a.length(),n=b.length();
        int[][] d=new int[m+1][n+1];
        for(int i=0;i<=m;i++)d[i][0]=i;  //空串與其他字串編輯距離的含義
        for(int j=0;j<=n;j++) d[0][j]=j;  
        for(int i=1;i<=m;i++){  
            for(int j=1;j<=n;j++){  
                if(a.charAt(i-1)==b.charAt(j-1)){  
                    d[i][j]=d[i-1][j-1];  
                }else{  
                    d[i][j]=1+Math.min(d[i-1][j-1], Math.min(d[i-1][j], d[i][j-1]));  
                }  
            }  
        } 
        System.out.println(d[m][n]);
        
    }  
}  

四則運算

注意 1、考慮負整數的處理。 2、將各種形式的括號都看成“(”和“)”,簡化處理。
import java.util.ArrayList; 
import java.util.Scanner;
import java.util.Stack;   

public class Main {   
    /** 將字串轉化成List */  
    public static ArrayList<String> getStringList(String str){  
        ArrayList<String> result = new ArrayList<String>();   
        StringBuilder num =new StringBuilder();  
        char pre='(';
        for (int i = 0; i < str.length(); i++) {  
            char c=str.charAt(i);
            if(Character.isDigit(c)||c=='-'){  
                if(c=='-'&&Character.isDigit(pre)){
                	//當前為“-”且前面為數字,為運算子
                    result.add(num.toString());
                    num.setLength(0);
                    result.add(str.charAt(i) + "");  
                }else{//普通數字或者數字的符號
                    num.append(c); 
                } 
            }else{
                if(num.length()!=0){  
                    result.add(num.toString());
                    num.setLength(0);
                }
                result.add(str.charAt(i) + ""); 
            }  
            pre=c;
        }  
        if(num.length() != 0){//對最後一個數做處理
            result.add(num.toString());
            num.setLength(0);
        }  
        return result;  
    }   
  /**比較運算子等級   */  
  public static boolean compare(String peek, String cur){  
      if("*".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
          return true;  
      }else if("/".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
          return true;  
      }else if("+".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
          return true;  
      }else if("-".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
          return true;  
      }  
      return false;  
  }  
    /** 將中綴表示式轉化為字尾表示式 */  
    public static ArrayList<String> getPostOrder(ArrayList<String> inOrderList){  
        ArrayList<String> result = new ArrayList<String>();  
        Stack<String> stack = new Stack<String>();  
        for (int i = 0; i < inOrderList.size(); i++) {  
            String s=inOrderList.get(i);
            if(Character.isDigit(s.charAt(0))||(s.length()>1&&s.charAt(0)=='-')){  
            	//此處包括正數和負數
                result.add(s);  
            }else{  
                switch (s.charAt(0)) {  
                case '(':  
                    stack.push(s);  
                    break;  
                case ')':  
                    while (!stack.peek().equals("(")) {  
                        result.add(stack.pop());  
                    }  
                    stack.pop();  
                    break;  
                default:  
                    while (!stack.isEmpty() && compare(stack.peek(),s)){  
                        result.add(stack.pop());  
                    }  
                    stack.push(s);  
                    break;  
                }  
            }  
        }  
        while(!stack.isEmpty()){  
            result.add(stack.pop());  
        }  
        return result;  
    }   
    /**  計算字尾表示式 */  
    public static Integer calculate(ArrayList<String> postOrder){  
        Stack<Integer> stack = new Stack<Integer>();  
        for (int i = 0; i < postOrder.size(); i++) {  
        	String s=postOrder.get(i);
            if(Character.isDigit(s.charAt(0))||(s.length()>1&&s.charAt(0)=='-')){  
            	//此處包括正數和負數
                stack.push(Integer.parseInt(postOrder.get(i)));  
            }else{  
                Integer back = (Integer)stack.pop();  
                Integer front = (Integer)stack.pop();  
                Integer res = 0;  
                switch (postOrder.get(i).charAt(0)) {  
                case '+':  
                    res = front + back;  
                    break;  
                case '-':  
                    res = front - back;  
                    break;  
                case '*':  
                    res = front * back;  
                    break;  
                case '/':  
                    res = front / back;  
                    break;  
                }  
                stack.push(res);  
            }  
        }  
        return (Integer)stack.pop();  
    }   
    public static void main(String[] args) {    
        Scanner in=new Scanner(System.in);
        String s=in.nextLine();//String s = "12+(23*3-56+7)*(2+90)/2";  
        s=s.replace('[', '(');
        s=s.replace(']', ')');
        s=s.replace('{', '(');
        s=s.replace('}', ')');  
        ArrayList<String> result =  getStringList(s);  //String轉換為List   
        result = getPostOrder(result);   //中綴變字尾    
        int i =  calculate(result);   //計算  
        System.out.println(i);   
    }  
}  

表示式求值

import java.util.ArrayList; 
import java.util.Scanner;
import java.util.Stack;   

public class Main {   
    /** 將字串轉化成List */  
    public static ArrayList<String> getStringList(String str){  
        ArrayList<String> result = new ArrayList<String>();   
        StringBuilder num =new StringBuilder();  
        for (int i = 0; i < str.length(); i++) {  
        	char c=str.charAt(i);
            if(Character.isDigit(c)){  
            	num.append(c); 
            }else{
                if(num.length()!=0){  
                    result.add(num.toString());
                    num.setLength(0);
                }
                result.add(str.charAt(i) + ""); 
            }  
        }  
        if(num.length() != 0){//對最後一個數做處理
            result.add(num.toString());
            num.setLength(0);
        }  
        return result;  
    }  
    
  /**比較運算子等級   */  
  public static boolean compare(String peek, String cur){  
      if("*".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
          return true;  
      }else if("/".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
          return true;  
      }else if("+".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
          return true;  
      }else if("-".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
          return true;  
      }  
      return false;  
  }  
    /** 將中綴表示式轉化為字尾表示式 */  
    public static ArrayList<String> getPostOrder(ArrayList<String> inOrderList){  
        ArrayList<String> result = new ArrayList<String>();  
        Stack<String> stack = new Stack<String>();  
        for (int i = 0; i < inOrderList.size(); i++) {  
            if(Character.isDigit(inOrderList.get(i).charAt(0))){  
                result.add(inOrderList.get(i));  
            }else{  
                switch (inOrderList.get(i).charAt(0)) {  
                case '(':  
                    stack.push(inOrderList.get(i));  
                    break;  
                case ')':  
                    while (!stack.peek().equals("(")) {  
                        result.add(stack.pop());  
                    }  
                    stack.pop();  
                    break;  
                default:  
                    while (!stack.isEmpty() && compare(stack.peek(), inOrderList.get(i))){  
                        result.add(stack.pop());  
                    }  
                    stack.push(inOrderList.get(i));  
                    break;  
                }  
            }  
        }  
        while(!stack.isEmpty()){  
            result.add(stack.pop());  
        }  
        return result;  
    }   
    /**  計算字尾表示式 */  
    public static Integer calculate(ArrayList<String> postOrder){  
        Stack<Integer> stack = new Stack<Integer>();  
        for (int i = 0; i < postOrder.size(); i++) {  
            if(Character.isDigit(postOrder.get(i).charAt(0))){  
                stack.push(Integer.parseInt(postOrder.get(i)));  
            }else{  
                Integer back = (Integer)stack.pop();  
                Integer front = (Integer)stack.pop();  
                Integer res = 0;  
                switch (postOrder.get(i).charAt(0)) {  
                case '+':  
                    res = front + back;  
                    break;  
                case '-':  
                    res = front - back;  
                    break;  
                case '*':  
                    res = front * back;  
                    break;  
                case '/':  
                    res = front / back;  
                    break;  
                }  
                stack.push(res);  
            }  
        }  
        return (Integer)stack.pop();  
    }   
    public static void main(String[] args) {    
		Scanner in=new Scanner(System.in);
    	String s=in.nextLine();//String s = "12+(23*3-56+7)*(2+90)/2";  
        ArrayList<String> result =  getStringList(s);  //String轉換為List  
        result = getPostOrder(result);   //中綴變字尾   
        int i =  calculate(result);   //計算  
        System.out.println(i);  
        System.out.println("true"); 
    }  
}  

無線OSS-高精度整數加法

import java.util.Scanner;   

public class Main {   
	private static void reverse(char[] a){
		int begin=0,end=a.length-1;
		while(begin<end){
			char t=a[begin];a[begin]=a[end];a[end]=t;
			begin++;end--;
		}
	}
	private static String add(String a,String b){
		char[] ac=a.toCharArray();
		char[] bc=b.toCharArray();
		reverse(ac);
		reverse(bc);//逆序,低位在前
		if(ac.length<bc.length){
			char[] t=ac;ac=bc;bc=t;
		}//保證ac要長
		char[] res=new char[ac.length];
		int add=0;
		for(int i=0;i<ac.length;i++){
			int first=ac[i]-'0';
			int second=i>=bc.length?0:bc[i]-'0';
			int sum=first+second+add;
			add=sum/10;
			res[i]=(char)(sum%10+'0');
		}
		reverse(res);
		return add==0?new String(res):"1"+new String(res); 
	}
	private static String sub(String a,String b){//a比b大
		char[] ac=a.toCharArray();
		char[] bc=b.toCharArray();
		reverse(ac);
		reverse(bc);//逆序,低位在前
		char[] res=new char[ac.length];
		int borrow=0;//借位
		for(int i=0;i<ac.length;i++){
			int first=ac[i]-'0'-borrow;
			int second=i>=bc.length?0:bc[i]-'0';
			if(first<second){
				borrow=1;
				res[i]=(char)(10+first-second+'0');
			}else{
				res[i]=(char)(first-second+'0');
			} 
		}
		boolean find=false; 
		StringBuilder builder=new StringBuilder();
		for(int i=res.length-1;i>=0;i--){//過濾掉高位的零
			if(find==false){
				if(res[i]!='0'){
					find=true;
					builder.append(res[i]);
				}
			}else{
				builder.append(res[i]);
			}
		}
		return builder.toString();
		
	}
	private static int compare(String a,String b){
		if(a.length()!=b.length()){
			return a.length()<b.length()?-1:1;
		}
		for(int i=0;i<a.length();i++){
			if(a.charAt(i)!=b.charAt(i)){
				return a.charAt(i)<b.charAt(i)?-1:1;
			}
		}
		return 0;
	}
    public static void main(String[] args) {   
        Scanner in=new Scanner(System.in); 
        String numA=in.next();
        String numB=in.next();
        int signA=1,signB=1;
        if(numA.charAt(0)=='-'){
        	signA=-1;
        	numA=numA.substring(1);
        }
        if(numB.charAt(0)=='-'){
        	signB=-1;
        	numB=numB.substring(1);
        }
        if(signA==signB){//符號相同做加法
        	System.out.println(signA==1?add(numA,numB):"-"+add(numA,numB)); 
        }else{//異號做減法
        	if(signA==-1){//使得numA為正數,numB為負數
        		signA=1;signB=-1;
        		String t=numA;numA=numB;numB=t;
        	}
        	int resSign=compare(numA,numB);
        	if(resSign==0){
        		System.out.println("0");
        	}else{
        		if(resSign<0){//結果為負數
        			System.out.println("-"+sub(numB,numA));
        		}else{//結果為整數
        			System.out.println(sub(numA,numB));
        		}
        	}
        }
        
    }  
}  


查詢兩個字串a,b中的最長公共子串

import java.util.Scanner;   
public class Main{   
    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);   
        String a=in.next();  
        String b=in.next();  
        int m=a.length(),n=b.length();  
        int[][] d=new int[m+1][n+1];  //d[i][j]表示以a[i]結尾的子串與b[j]結尾的子串的最長公共長度
        int max=0,maxEnd = 0;  
        for(int i=1;i<=m;i++){  
            for(int j=1;j<=n;j++){  
                if(a.charAt(i-1)==b.charAt(j-1)){  
                    d[i][j]=d[i-1][j-1]+1;  
                    if(d[i][j]>max){  
                        max=d[i][j];  
                        maxEnd=i;  
                    }  
                }else{  
                    d[i][j]=0;  
                }  
            }  
        }  
        System.out.print(a.substring(maxEnd-max,maxEnd));  
    }  
} 

成績排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;  

public class Main {   
	static int mark=0;
	private static class Student implements Comparable{
		String name;
		int score;
		Student(String name,int score){
			this.name=name;
			this.score=score;
		}
		@Override
		public int compareTo(Object obj) { 
			Student comp=(Student)obj;
			int res=-1;
			if(this.score==comp.score){
				if(this.name.toLowerCase().compareTo(comp.name.toLowerCase())==0){//忽略大小寫比較
					return 0;
				}else{
					res=this.name.toLowerCase().compareTo(comp.name.toLowerCase())<0?-1:1;
				}
			}else{
				res=this.score<comp.score?-1:1;
			}
 
			return mark==1?res:res*-1;
		}
	}
 
    public static void main(String[] args) {   
        Scanner in=new Scanner(System.in);  
        int n=in.nextInt();  
        mark=in.nextInt();
        if(n<=0) return;  
        ArrayList<Student> list=new ArrayList<Student>();
        for(int i=0;i<n;i++){   
        	Student t=new Student(in.next(),in.nextInt());
        	list.add(t);
        }  
        Collections.sort(list);
        for(Student s:list){
        	System.out.println(s.name+" "+s.score);
        }
    }  
}  

引數解析

import java.util.LinkedList; 
import java.util.Scanner; 
 

public class Main {
 
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		LinkedList<String> commands=new LinkedList<String>();
		while(sca.hasNext()){
			commands.add(sca.next());
		}
		if(commands.size()==0) {System.out.println(0);return;}
		int index=0; 
		while(index<commands.size()){
			String s=commands.get(index);
			if(s.charAt(0)!='\"'){//簡單命令不做任何處理
				index++; 
			}else{
				if(s.charAt(0)=='\"'&&s.charAt(s.length()-1)=='\"'){//兩頭都是",去掉兩頭的"
					commands.set(index, s.substring(1,s.length()-1));
					index++;
				}else{//只有一頭是",將後續的字串拼接過來
					commands.set(index, s+" "+commands.get(index+1));
					commands.remove(index+1);
				}
			}
		}
		System.out.println(commands.size());
		for(String command:commands){
			System.out.println(command);
		}
	} 
}

字串運用-密碼擷取

分析

該問題就是最長迴文子串的問題。可以採用動態規劃演算法。

除了採用動態規劃演算法,還可以採用中心擴充套件法:即依次以每個字元為中心向兩邊擴充套件,尋找最長迴文長度。

import java.util.Scanner; 

public class Main { 
	private static int  longestPalindrome(String s){
		int n=s.length(),max=1;
		if(n==0)return 0; 
		boolean[][] d=new boolean[n][n];
		for(int i=0;i<n;i++){
			d[i][i]=true;
		}
		for(int i=n-2;i>=0;i--){
			for(int j=i+1;j<n;j++){
				if(s.charAt(i)==s.charAt(j)){//首尾相等
					if(i+1==j||d[i+1][j-1]==true){
						d[i][j]=true;
						max=Math.max(max, j-i+1);
					}
				}
			}
		} 
		return max;
	}
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		String s=sca.next();
		System.out.println(longestPalindrome(s));
	} 
}

24點

import java.util.ArrayList;
import java.util.Collections; 
import java.util.List; 
import java.util.Scanner;
import java.util.Stack;
 

public class Main {
    //比較符號優先順序
    public static boolean compare(String peek, String cur){  
        if("*".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
            return true;  
        }else if("/".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){  
            return true;  
        }else if("+".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
            return true;  
        }else if("-".equals(peek) && ("+".equals(cur) || "-".equals(cur))){  
            return true;  
        }  
        return false;  
    }  
    // 將中綴表示式轉化為字尾表示式  
    public static ArrayList<String> getPostOrder(List<String> inOrderList){   
        ArrayList<String> result = new ArrayList<String>();  
        Stack<String> stack = new Stack<String>();  
        for (int i = 0; i < inOrderList.size(); i++) {  
            if(Character.isDigit(inOrderList.get(i).charAt(0))){  
                result.add(inOrderList.get(i));  
            }else{  
                switch (inOrderList.get(i).charAt(0)) {  
                case '(':  
                    stack.push(inOrderList.get(i));  
                    break;  
                case ')':  
                    while (!stack.peek().equals("(")) {  
                        result.add(stack.pop());  
                    }  
                    stack.pop();  
                    break;  
                default:  
                    while (!stack.isEmpty() && compare(stack.peek(), inOrderList.get(i))){  
                        result.add(stack.pop());  
                    }  
                    stack.push(inOrderList.get(i));  
                    break;  
                }  
            }  
        }  
        while(!stack.isEmpty()){  
            result.add(stack.pop());  
        }  
        return result;  
    }  

    // 計算字尾表示式  
    public static Integer calculate(ArrayList<String> postOrder){  
        Stack<Integer> stack = new Stack<Integer>();  
        for (int i = 0; i < postOrder.size(); i++) {  
            if(Character.isDigit(postOrder.get(i).charAt(0))){  
                stack.push(Integer.parseInt(postOrder.get(i)));  
            }else{  
                Integer back = (Integer)stack.pop();  
                Integer front = (Integer)stack.pop();  
                Integer res = 0;  
                switch (postOrder.get(i).charAt(0)) {  
                case '+':  
                    res = front + back;  
                    break;  
                case '-':  
                    res = front - back;  
                    break;  
                case '*':  
                    res = front * back;  
                    break;  
                case '/':  
                	//如果除數為0、除數小於被除數、被除數不能被整除不是合法的計算方式
                	if(back==0||front<back||front%back!=0)return 0;
                    res = front / back;  
                    break;  
                }  
                stack.push(res);  
            }  
        }  
        return (Integer)stack.pop();  
    }  
    //獲取全排列
    private static List<List<String>> getAllPermutation(ArrayList<String> values){
    	List<List<String>> res=new ArrayList<List<String>>();
    	doPermutation(res,values,0);
		return res;
    	
    }
    private static void doPermutation(List<List<String>> res,ArrayList<String> values,int index ){
    	if(index==values.size()-1){
    		@SuppressWarnings("unchecked")
			ArrayList<String> r=(ArrayList<String>) values.clone();
    		res.add(r);
    		return;
    	}
    	for(int i=index;i<values.size();i++){
    		Collections.swap(values, index, i);
    		doPermutation(res,values,index+1);
    		Collections.swap(values, index, i);
    	} 
    }

	@SuppressWarnings("resource")
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		ArrayList<String> values=new ArrayList<String>();//數值集合
		for(int i=0;i<4;i++){
			String s=sca.next();
			if(s.equals("joker")||s.equals("JOKER")){//非法輸入檢查
				System.out.println("ERROR");
				return;
			}else{
				char c=s.charAt(0);
				if('2'<=c&&c<='9'){
					values.add(s);
				}else{
					if(s.equals("10"))values.add(s);
					if(c=='A')values.add("1");
					if(c=='J')values.add("11");
					if(c=='Q')values.add("12");
					if(c=='K')values.add("13");
				}
			}
		}
		List<List<String>>  allValues=getAllPermutation(values);//獲取數字的全排列
		String[] operators={"+","-","*","/"};
		for(List<String> list:allValues){//測試數字組合
			
			for(int i=0;i<4;i++){//測試各種符號組合
				for(int j=0;j<4;j++){
					for(int k=0;k<4;k++){ 
						List<String> expression=new ArrayList<String>();
						expression.add(list.get(0));
						expression.add(operators[i]);
						expression.add(list.get(1));
						expression.add(operators[j]);
						expression.add(list.get(2));
						expression.add(operators[k]);
						expression.add(list.get(3)); 
						//計算表示式
						Integer res =calculate(getPostOrder(expression));
						if(res.equals(24)){
							for(String s:expression){
								System.out.print(s);
							}
							return;
						}
					}
				}
			}
		} 
		System.out.println("NONE"); 
	} 
}

201301 JAVA 題目2-3級

分析

動態規劃。

定義:d[i][j]表示從點a[0][0]到點a[i][j]的所有路徑數。

遞推表示式:d[i][j]=d[i-1][j]+d[i][j-1]

import java.util.Scanner;

public class Main { 
	public static void main(String[] args) {  
		Scanner sca=new Scanner(System.in);
		int m=sca.nextInt()+1,n=sca.nextInt()+1;//邊緣線轉換成點 
		int[][] d=new int[m+1][n+1];
		d[1][1]=1;
		for(int i=1;i<=m;i++){
			for(int j=1;j<=n;j++){ 
				if(i==1&&j==1){continue;}
				d[i][j]=d[i-1][j]+d[i][j-1];
			}
		}
		System.out.println(d[m][n]); 
	}
}

輸入整型陣列和排序標識,對其元素按照升序或降序進行排序

public class Main {   
    private static int mark=0;  
    public static class MyComparator implements Comparator{  
        @Override  
        public int compare(Object arg0, Object arg1) {  
            int a=(int)arg0,b=(int)arg1;  
            if(a==b) return 0;  
            if(a<b){  
                return mark==0?-1:1;  
            }else{  
                return mark==0?1:-1;  
            }  
        }  
    }  
    public static void main(String[] args) {   
        Scanner sca=new Scanner(System.in);  
        int n=sca.nextInt();   
        ArrayList<Integer> nums=new ArrayList<Integer>();   
        for(int i=0;i<n;i++){  
            nums.add(sca.nextInt());  
        }  
        mark=sca.nextInt();  
        Collections.sort(nums, new MyComparator());  
        for(int i=0;i<n-1;i++){  
            System.out.print(nums.get(i)+" ");  
        }  
        System.out.print(nums.get(n-1));  
    }  
}  

Redraiment的走法

分析

該問題實質上就是求最長上升子序列的問題。採用動態規劃演算法。

定義:d[i]表示以a[i]結尾的最長上升子序列長度。

遞推表示式:d[i]=max{d[j]+1},d[j]<d[i]且j<i

import java.text.DecimalFormat;
import java.util.Scanner;

public class Main { 
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		int n=sca.nextInt(),res=1; 
		int[] heights=new int[n];
		int[] counts=new int[n];//表示以heights[i]結尾的最長上升序列長度
		for(int i=0;i<n;i++){  
			heights[i]=sca.nextInt();
			counts[i]=1; 
		}
		for(int i=1;i<n;i++){
			int max=0;
			for(int j=0;j<i;j++){
				if(heights[j]<heights[i]){//前面的小於當前元素
					max=Math.max(max, counts[j]);
				}
			}
			counts[i]=max+1;
			res=Math.max(res, counts[i]);
		}
		System.out.print(res);
	}
}

字串分割

import java.util.Scanner;  
  
public class Main {   
    private static String zeroStr(int n){  
        StringBuilder builder=new StringBuilder();  
        for(int i=0;i<n;i++){  
            builder.append('0');  
        }  
        return builder.toString();  
    }  
    private static void printStr(String s){  
        int begin=0;  
        while(begin<s.length()){  
            System.out.println(s.substring(begin,begin+8));  
            begin+=8;  
        }  
    }  
    public static void main(String[] args) {   
        Scanner sca=new Scanner(System.in);  
        int n=sca.nextInt();  
        if(n<=0) return;  
        for(int i=0;i<n;i++){  
            String s=sca.next();   
            if(s.length()%8!=0){  
                s+=zeroStr(8-s.length()%8);  
            }   
            printStr(s);  
        }  
    }  
}  

記負均正

import java.text.DecimalFormat;
import java.util.Scanner;

public class Main { 
 
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		int navigateCount=0,positiveCount=0;
		double sum=0.0;
		while(sca.hasNext()){
			int i=sca.nextInt();  
			if(i<0){
				navigateCount++;
			}else{
				positiveCount++;
				sum+=i;
			}
		}
		double average=positiveCount==0?0.0:sum/positiveCount;//防止除數為零
		DecimalFormat df=new DecimalFormat("#.0");  //保留一位小數
		System.out.println(navigateCount); 
		System.out.println(df.format(average));
	}
}

字串分割

分析

先對每個輸入字串進行補齊,然後統一分割。

import java.util.Scanner;

public class Main { 
	private static String zeroStr(int n){
		StringBuilder builder=new StringBuilder();
		for(int i=0;i<n;i++){
			builder.append('0');
		}
		return builder.toString();
	}
	private static void printStr(String s){
		int begin=0;
		while(begin<s.length()){
			System.out.println(s.substring(begin,begin+8));
			begin+=8;
		}
	}
	public static void main(String[] args) { 
		Scanner sca=new Scanner(System.in);
		while(sca.hasNext()){
			String s=sca.next(); 
			if(s.length()%8!=0){
				s+=zeroStr(8-s.length()%8);
			} 
			printStr(s);
		}
	}
}