1
輸入:第一行爲操作總數Q,之後有Q行。每行一個操作。
操作1,將字符串加在原字符串末尾。
操作2,給定長度,從字符串末尾刪除。
操作3,查詢現在字符串中第k個字符。
操作4,回滾一次操作(只回滾增刪操作)。
難度:easy
耗時:10min
public class Main {
static StringBuilder sb = new StringBuilder();
static Stack<String> st = new Stack();
private static void add(String s) {
st.push(sb.toString());
sb.append(s);
}
private static char search(int pos) {
return sb.charAt(pos-1);
}
private static void delete(int len) {
st.push(sb.toString());
sb.setLength(sb.length() - len);
}
private static void rollback() {
sb = new StringBuilder(st.pop());
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int Q = sc.nextInt();
sc.nextLine();
for (int j = 0; j < Q; j++) {
String[] arr = sc.nextLine().split("\\s+");
if (arr[0].equals("1"))
add(arr[1]);
else if (arr[0].equals("2"))
delete(Integer.parseInt(arr[1]));
else if (arr[0].equals("3")) {
char c = search(Integer.parseInt(arr[1]));
System.out.println(c);
} else
rollback();
}
}
}
2
輸入:第一行爲需要翻譯的文本M。len(M) <= 50000.
第二行爲字典中單詞數n。2 <= n <= 50000.
每一個單詞長度不超過20。
之後有n行,每一行代表一個單詞。
返回總共有多少種翻譯文本的方式。
返回的結果需要%835672545。
樣例:
abcba
5
a
ab
ba
bc
cb
// 輸出2
ab | cb | a
a | bc | ba
難度:medium
耗時:50min
一開始沒有降維,MLE。
public class Main {
static final int kMod = 835672545;
private static int search(HashSet<String> dict, String s) {
int n = s.length();
int[][] dp = new int[n+1][n+1];
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) {
String tmp = s.substring(i-1, j);
if (dict.contains(tmp))
dp[i][j] = 1;
}
for (int len = 1; len <= n; len++) {
for (int i = 1; i+len-1 <= n; i++) {
int j = i + len - 1;
for (int k = i; k < j; k++) {
String s2 = s.substring(k, j);
if (dp[i][k] > 0 && dict.contains(s2)) {
dp[i][j] = (dp[i][j] + dp[i][k]) % kMod;
}
}
}
}
// System.out.println(dp[1][1]); //a
// System.out.println(dp[1][2]); // ab
// System.out.println(dp[1][3]); // a | bc
// System.out.println(dp[1][4]); // ab | cb
return dp[1][n];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String target = sc.nextLine();
int Q = sc.nextInt();
sc.nextLine();
HashSet<String> dict = new HashSet();
for (int j = 0; j < Q; j++) {
dict.add(sc.nextLine());
}
System.out.println(search(dict, target));
}
}
第二次,沒有用Math.max優化長度,TLE。而且顯示test case通過率爲0,特別慌。
第三次終於AC。
public class Main {
static final int kMod = 835672545;
private static int search(HashSet<String> dict, String s) {
int n = s.length();
int[] dp = new int[n+1];
dp[0] = 1;
for (int r = 1; r <= n; r++) {
for (int l = Math.max(1, r-20); l <= r; l++) {
String tmp = s.substring(l-1, r);
if (dp[l-1] > 0 && dict.contains(tmp))
dp[r] = (dp[r] + dp[l-1]) % kMod;
}
}
return dp[n];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String target = sc.nextLine();
int Q = sc.nextInt();
sc.nextLine();
HashSet<String> dict = new HashSet();
for (int j = 0; j < Q; j++) {
dict.add(sc.nextLine());
}
System.out.println(search(dict, target));
}
}
3
輸入:第一行兩個整形,m表示天數,n表示襪子數量(只)。
第二行是每隻襪子的顏色(用整形表示)。
之後有m行,每一天穿兩隻固定序號的襪子。但是必須保證兩隻襪子顏色一樣。如果不一樣,需要塗改襪子的顏色使這兩隻襪子的顏色能夠匹配。代價爲1。
返回最小代價。
難度:medium - hard
耗時:10min
應該是個dp問題。但是我連暴力解都沒寫出來。下面是個錯誤解法。
public class Main {
static int[] color;
static int[] color2;
static int[][] comb;
static int m;// number of days
static int n;// number of socks
private static int paint() {
// dp[i][j][k] := min number of painting
// in day i, painting j-th sock to color k
// int[][][] dp = new int[m+1][n][n];
// dp[0] = color.clone();
int cnt = 0;
for (int i = 0; i < m; i++) {
int sock1 = comb[i][0];
int sock2 = comb[i][1];
boolean same1 = true;
boolean same2 = true;
if (color[sock1] != color[sock2]) {
color[sock1] = color[sock2];
same1 = false;
}
if (color2[sock1] != color2[sock2]) {
color2[sock2] = color2[sock1];
same2 = false;
}
if (!same1 && !same2)
cnt++;
}
return cnt;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
color = new int[n+1];
comb = new int[m][2];
for (int i = 1; i <= n; i++) {
int c = sc.nextInt();
color[i] = c;
}
color2 = color.clone();
sc.nextLine();
for (int j = 0; j < m; j++) {
String[] arr = sc.nextLine().split("\\s");
comb[j][0] = Integer.parseInt(arr[0]);
comb[j][1] = Integer.parseInt(arr[1]);
}
System.out.println(paint());
}
}
4
對給定字符串有兩種操作。
操作1,修改第k個字符爲新字符c。
操作2,查詢給定範圍內不同字符的個數。
難度:hard
耗時:10min
沒寫出來,只寫了一個暴力解,60%測試用例超時。
我估計使用Trie。
public class Main {
static StringBuilder sb = null;
private static int query(int l, int r) {
HashSet<Character> cnt = new HashSet();
for (int i = l-1; i < r; i++) {
cnt.add(sb.charAt(i));
}
return cnt.size();
}
private static void update(int pos, String s) {
sb.setCharAt(pos-1, s.charAt(0));
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String target = sc.nextLine();
sb = new StringBuilder(target);
int Q = sc.nextInt();
sc.nextLine();
HashSet<String> dict = new HashSet();
for (int j = 0; j < Q; j++) {
String[] arr = sc.nextLine().split("\\s");
if (arr[0].equals("2")) { // query
System.out.println(query(Integer.parseInt(arr[1]), Integer.parseInt(arr[2])));
} else {
update(Integer.parseInt(arr[1]), arr[2]);
}
}
}
}
做完心態是崩潰的。