@蓝桥杯 练习系统 ALGO-24
@洛谷 P1029
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份 (1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例 如字符串this中可包含this和is,选用this之后就不能包含th)。
单词在给出的一个不超过6个单词的字典中。
要求输出最大的个数。
输入格式
第一行有二个正整数(p,k)
p表示字串的行数;
k表示分为k个部分。
接下来的p行,每行均有20个字符。
再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
接下来的s行,每行均有一个单词。
输出格式
每行一个整数,分别对应每组测试数据的相应结果。
测试样例
输入:
1 3
thisisabookyouareaoh
4
is
a
ok
sab
输出:
7
数据规模与约定
长度不超过200,1<k<=40,字典中的单词数不超过6。
AC code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] pk = in.readLine().split(" ");
int p = Integer.parseInt(pk[0]) * 20,
cnt[][] = new int[p + 1][p + 1],
k = Integer.parseInt(pk[1]),
dp[][] = new int[p][k],
flg[] = new int[p];
char[] str = new char[p];
for (int i = 0; i < p; i += 20)
in.readLine().getChars(0, 20, str, i);
int s = Integer.parseInt(in.readLine());
char[][] words = new char[s][];
while (s-- > 0) words[s] = in.readLine().toCharArray();
for (char[] word: words) {
agent: for (int i = p - word.length; i >= 0; i--)
if (str[i] == word[0]) {
for (int j = word.length - 1; j >= 1; j--) if (str[i + j] != word[j]) continue agent;
flg[i] = i + word.length - 1;
}
}
for (int j = p - 1; j >= 0; j--)
for (int i = j; i >= 0; i--) {
cnt[i][j] += cnt[i + 1][j];
if (flg[i] != 0 && flg[i] <= j) cnt[i][j]++;
}
for (int i = 0; i < p; i++) {
dp[i][0] = cnt[0][i];
for (int j = 1; j < k; j++)
for (int l = j + 1; l < i; l++)
dp[i][j] = max(dp[i][j], dp[l][j - 1] + cnt[l + 1][i]);
}
System.out.print(dp[p - 1][k - 1]);
}
static int max(int a, int b) { return a > b? a: b; }
}
被洛谷的测试数据恶心到了,本来很快乐的模拟题,为什么会这么折磨呢
AC code (蓝桥) :
public class Main {
public static void main(String[] args) {
SystemIn in = new SystemIn();
int len = in.nextInt() * 20, k = in.nextInt() - 1, cnt = 0;
int[] str = new int[len];
boolean[] marked = new boolean[len];
in.arraycopy(str, 0, len);
int s = in.nextInt();
char[][] words = new char[s][];
for (int i = 0; i < s; i++) words[i] = in.next().toCharArray();
mainActor: for (int i = 0; i < len; i++) {
judge: for (int j = 0; j < s; j++) {
if (str[i] == words[j][0] && len - i >= words[j].length)
for (int l = 1; l < words[j].length; l++) { if (str[i + l] != words[j][l]) continue judge; }
else continue;
for (int l = words[j].length - 1 + i; l >= i; l--) marked[l] = true;
cnt++;
continue mainActor;
}
if (k > 0 && !marked[i]) k--;
}
System.out.print(cnt - k);
}
static class SystemIn {
byte[] inBuff;
int lenBuff;
int inLne;
SystemIn() { this(1024); }
SystemIn(int size) {
this.inBuff = new byte[size];
this.lenBuff = this.inLne = 0;
}
int getByte() {
if (lenBuff >= inLne) {
lenBuff = 0;
try { inLne = System.in.read(inBuff);
} catch (java.io.IOException e) { e.printStackTrace(); }
if (inLne == 0) return -1;
}
return inBuff[lenBuff++];
}
String next() {
StringBuilder res = new StringBuilder();
int b;
while ((b = getByte()) <= 32);
while (b > 32) {
res.appendCodePoint(b);
b = getByte();
}
return res.toString();
}
int nextInt() { return Integer.parseInt(next()); }
void arraycopy(int[] arg, int offset, int size) {
int b;
while (offset < size){
b = getByte();
if (b > 32) arg[offset++] = b;
}
}
}
}
在我一开始的设想中,需要把字母串分为四种类型,再整合出结果
但是先写个模板一遍就跑过了,只能说测试数据也就那样