2018年11月12日 星期一

Q441:Lotto

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=382


這題是利用回朔言算法來枚舉,排列出所有的可能組合,題目要求輸入一串數列,第一個數字(k)代表接下來後面會有幾個數字,最後就會從S1~Sk中取六個出來的所有組合。

在解這提前可以思考如何利用回朔法來將1 2 3 4 5這五個數字取三個出來的組合,答案如下,總共十個:
注意 1 2 3 和 1 3 2 是一樣的所以每個答案是要從小到大排列,請參考Main.java

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 


若沒有大小順序限制則要建立一個check[]陣列來檢查目前此數是否在答案中且不重複(程式碼請參考Main2.java)


題目要求由小至大所以我們拿第一個程式下去修改實做(參Q441:Lotto.java)

public class Main {
static int arr[]= {1,2,3,4,5}; // S集合
static int ans[]=new int[3]; // 從集合中取三個的組合
static int check[]=new int[5]; // 檢查該數是否在ans[]集合中
public static void main(String[] args) {
backtracking(0);
}
public static void backtracking(int n) {
if(n==3) { // 若dimension維度是第三層代表找完答案依序印出並結束遞迴
for(int i=0;i<3;i++) {
System.out.print(ans[i]+" ");
}
System.out.println();
return;
}
for(int i=0;i<5;i++) {
if(check[i]==0) {// 判斷該數是否已經出現在ans[]中
check[i]=1;
ans[n]=arr[i];
backtracking(n+1);
check[i]=0;
}
}
}
/* 五個數字取三個所有組合(無大小順序限制)
作者:1010
時間:西元 2018 年 11 月 */
}
public class Main {
static int arr[]= {1,2,3,4,5}; // S集合
static int ans[]=new int[3]; // 從集合中取三個的組合
public static void main(String[] args) {
backtracking(0,0);
}
public static void backtracking(int n,int pos) {
if(n==3) { // 若dimension維度是第三層代表找完答案依序印出並結束遞迴
for(int i=0;i<3;i++) {
System.out.print(ans[i]+" ");
}
System.out.println();
return;
}
for(int i=pos;i<5;i++) {// 每次遞迴從pos開始這樣就不會遇到重複值
ans[n]=arr[i];
backtracking(n+1,i+1);
}
}
/* 五個數字取三個並由小到大排列
作者:1010
時間:西元 2018 年 11 月 */
}
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static public ArrayList < Integer > list;
static public int[] solution;
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
int count = 0;
while (true) {
String arr[] = scn.nextLine().split(" ");
if (arr[0].equals("0"))
break;
if (count != 0)
System.out.println();
list = new ArrayList<Integer>();
for (int i = 1; i < arr.length; i++)
list.add(Integer.parseInt(arr[i]));
solution = new int[6];
used = new int[list.size()];
backtracking(0, 0);
count++;
}
}
public static void backtracking(int n, int pos) {
if (n == 6) {
for (int i = 0; i < 6; i++) {
if (i != 0)
System.out.print(" ");
System.out.print(solution[i]);
}
System.out.println();
return;
}
for (int i = pos; i < list.size(); i++) {
solution[n] = list.get(i);
backtracking(n + 1, i + 1);
}
}
/*題目:UVA Q441:Lotto
作者:1010
時間:西元 2018 年 11 月 */
}

2018年3月28日 星期三

[C_ST49-易] 字串取代

https://e-tutor.itsa.org.tw/e-Tutor/mod/programming/view.php?id=7009

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
String str=scn.nextLine();
String arr[]= {"hate","stupid","angry","dirty"},arr2[]= {"love","smart","happy","clean"};
for(int i=0;i<4;i++)
str = str.replaceAll(arr[i], arr2[i]);
System.out.println(str);
}
/*題目:[C_ST49-易] 字串取代
作者:1010
時間:西元 2018 年3 月 */
}

這題直接用JAVA的(replaceAll)將單字做取代替換就行了

[C_ST35-易] 抱怨值問題

https://e-tutor.itsa.org.tw/e-Tutor/mod/programming/view.php?a=1154

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
String str=scn.nextLine().replaceAll(" ", "");
String arr[]=str.split(",");
int count =0;
for(int i=0;i<arr.length;i++) {
for(int j=i-1;j>=0;j--) {
if(Integer.parseInt(arr[i])<Integer.parseInt(arr[j]))
count++;
}
}
System.out.println("Complaint ="+count);
}
/*題目:[C_ST35-易] 抱怨值問題
作者:1010
時間:西元 2018 年3 月 */
}

一開始寫完交出去結果回傳1,仔細看題目發現原來數字間除了逗號外還可能包含多個空白!
所以解婕辦法是先將所有的空白用(replaceAll)取代空字串,最後再用(split)來切逗號數字,這題是找目前數字之前有幾個比自己還大,所以利用O(n2)方式下去搜。

[C_ST38-中] 字數統計

https://e-tutor.itsa.org.tw/e-Tutor/mod/programming/view.php?id=2691

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
String str="";
while(scn.hasNext()) {
str+=scn.nextLine()+" ";
}
str=str.replaceAll("[,.;?!-]", "");
String arr[]=str.split(" ");
ArrayList<String> list = new ArrayList<String>();
ArrayList<Integer> count = new ArrayList<Integer>();
int j=0;
for(int i=0;i<arr.length;i++) {
if(arr[i].equals(""))
continue;
for(j=0;j<list.size();j++) {
if(list.get(j).toLowerCase().equals(arr[i].toLowerCase())) {
count.set(j, count.get(j)+1);
break;
}
}
if(j==list.size()) {
list.add(arr[i]);
count.add(1);
}
}
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i)+" : "+count.get(i));
}
}
/*題目:[C_ST38-中] 字數統計
作者:1010
時間:西元 2018 年3 月 */
}
題目有說道要去除標點符號,所以利用字串取代(replaceAll)將遇到的標點符號改為空字串,之後再使用字串切割(split)將字串切成陣列,最後在陣列走訪依序的計算每個單字的數量,比對單字是否存在時可以統一將單字轉成小寫(toLowerCase)

2017年11月28日 星期二

Q272 : TEX Quotes

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=208

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
int count =0;
while(scn.hasNext()) {
char str[]=scn.nextLine().toCharArray();
for(int i=0;i<str.length;i++) {
if(str[i]=='\"') {
if(count%2==0)
System.out.print("``");
else
System.out.print("''");
count++;
}else
System.out.print(str[i]);
}
System.out.println();
}
}
}

這題別想太複雜把獨到的每列字串轉成字元陣列再一個一個下去找雙引號,記住每行 ` ' 的順序延續上一行,所以我把count放在最外層

範例測資:
Input:

"""

"""
Output:

``''``

''``''

2017年10月17日 星期二

ITSA第58次月賽 Problem 3. 完整二元樹

http://e-tutor.itsa.org.tw/e-Tutor/mod/programming/view.php?id=38906

import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
Scanner scn =new Scanner(System.in);
int t=Integer.parseInt(scn.nextLine());
while(t--!=0) {
int n=Integer.parseInt(scn.nextLine()),index=1,x=0,b=0;
StringTokenizer tokens = new StringTokenizer(scn.nextLine(),"(),");
int arr[]=new int [tokens.countTokens()/2];
while(tokens.hasMoreTokens()) {
if(index%2==0)
arr[x++]=Integer.parseInt(tokens.nextToken());
else
tokens.nextToken();
index++;
}
for(int i=1;i<=Math.ceil(arr.length/2);i++){
if(Math.abs(arr[i-1]-arr[2*i-1])<=n) {
if(b!=0)
System.out.print(" ");
System.out.printf("%c%c",i+64,i*2+64);
b=1;
}
if(Math.abs(arr[i-1]-arr[2*i])<=n) {
if(b!=0)
System.out.print(" ");
System.out.printf("%c%c",i+64,i*2+65);
b=1;
}
}
System.out.println();
}
}
/*題目:ITSA第58次月賽 Problem 3. 完整二元樹
作者:1010
時間:西元 2017 年10 月 */
}
這題不要看到是樹就想得很害怕又複雜,其實他一點跟樹的演算法都無關仔細看看可以發現規律並用簡單數學就能推出答案囉!


ITSA第58次月賽 Problem 2. 道路修補

http://e-tutor.itsa.org.tw/e-Tutor/mod/programming/view.php?id=38905

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scn =new Scanner(System.in);
int n=scn.nextInt();
while(n--!=0) {
int t=scn.nextInt(),max=0,tot=0;
Set<Integer> set = new HashSet<Integer>();
for(int i=0;i<t;i++) {
int x=scn.nextInt(),y=scn.nextInt();
for(int j=x+1;j<=y;j++) {
set.add(j);
}
}
System.out.println(set.size());
}
}
/*題目:ITSA第58次月賽 Problem 2. 道路修補
作者:1010
時間:西元 2017 年10 月 */
}

這題有兩種做法第一種最直覺建立長度10000的陣列把需要修補的道路依序塞入數值,另外找出裡面數值最大的數最後算修補的道路就從0~amx就好囉
第二種方法就是利用java中的set容器囉,他會自動地把重複數字砍掉最後算set的總長度就是答案囉!