希望决赛题目不搞我
先挂
本题满分: 15分
问题描述
少年宫新近邮购了小机器人配件,共有3类,其中,
A类含有:8个轮子,1个传感器
B类含有: 6个轮子,3个传感器
C类含有:4个轮子,4个传感器
他们一共订购了100套机器人,收到了轮子600个,传感器280个。
根据这些信息请你计算:B类型机器人订购了多少个?
答案提交
请直接提交该整数,不要填写任何多余内容。
60
calcCode:
public class Main {
public static void main(String[] args) throws IOException {
for (int A = 0; A <= 100; A++)
for (int B = 0; B <= 100; B++)
for (int C = 0; C <= 100; C++) {
if (A + B + C == 100 && A * 8 + B * 6 + C * 4 == 600 && A + B * 3 + C * 4 == 280) {
System.out.println(B);
return;
}
}
}
}
暴力
本题满分: 29分
问题描述
所谓回文数就是左右对称的数字,比如:
585,5885,123321…
当然,单个的数字也可以算作是对称的。
小明发现了一种生成回文数的方法:
比如,取数字19,把它与自己的翻转数相加:
19 + 91 = 110,如果不是回文数,就再进行这个过程:
110 + 011 = 121 这次是回文数了。
200以内的数字中,绝大多数都可以在30步以内变成回文数,只有一个数字很特殊,就算迭代了1000次,它还是顽固地拒绝回文!
答案提交
请你提交该顽固数字,不要填写任何多余的内容。
196
calcCode:
public class Test {
public static void main(String[] args) {
int num[] = new int[33554432], len = 0;
for (int k = 10, step; k < 200; k++) {
java.util.Arrays.fill(num, 0, len, 0);
num[0] = k;
len = init(num, 1);
for (step = 0; step < 1000; step++){
echo(num, len);
len = init(num, len);
if (check(num, len)) break;
}
if (step == 1000) System.out.println(k);
}
}
static int init(int[] num, int len) {
for (int i = 0; i < len; i++) {
if (num[i] >= 10) {
if (i == len - 1) len++;
num[i + 1] += num[i] / 10;
num[i] %= 10;
}
}
return len;
}
static void echo(int[]num, int len) {
for (int i = 0, j = len - 1; i <= j; i++, j--)
num[i] = num[j] = num[i] + num[j];
}
static boolean check(int[] num, int len) {
for (int i = 0, j = len - 1; i <= j; i++, j--)
if (num[i] != num[j]) return false;
return true;
}
}
本题满分: 37分
问题描述
小明刚刚开发了一个小程序,可以打印出任意规模的空心菱形,规模为6时,如下图:
他一高兴,踢掉了电源,最后一次修改没有保存…
毛病出在划线的部分。
请你帮助小明分析程序,填写划线部分缺失的代码。
public class Main
{
static String pr(int m, int n)
{
String s = "";
for(int i=0; i<n; i++) s += " ";
for(int i=0; i<m; i++) s = "*" + s + "*";
return s;
}
static void f(int n)
{
String s = pr(1,n*2-1) + "\n";
String s2 = s;
for(int i=1; i<n; i++){
s = ____________________________________; //填空位置
s2 = s + s2 + s;
}
System.out.print(s2);
}
public static void main(String[] args)
{
f(6);
}
}
答案提交
注意:只填写缺少的内容,不要填写题面已有代码或说明性文字。
s.replaceAll("\\* | \\*", "**")
优雅
时间限制: 1.0s 内存限制: 512.0MB 本题满分: 31 分
问题描述
从X星截获一份电码,是一些数字,如下:
13
1113
3113
132113
1113122113
…
YY博士经彻夜研究,发现了规律:
第一行的数字随便是什么,以后每一行都是对上一行“读出来”
比如第2行,是对第1行的描述,意思是:1个1,1个3,所以是:1113
第3行,意思是:3个1,1个3,所以是:3113
请你编写一个程序,可以从初始数字开始,连续进行这样的变换。
输入格式
第一行输入一个数字组成的串,不超过100位
第二行,一个数字n,表示需要你连续变换多少次,n不超过20
输出格式
输出一个串,表示最后一次变换完的结果。
测试样例1
Input:
5
7
Output:
13211321322115
code:
import java.io.*;
import java.util.ArrayDeque;
import java.util.Deque;
public class Main {
static final int INF = 0x3F3F3F3F;
public static void main(String[] args) {
PrintWriter out = new PrintWriter(System.out);
Deque<Integer> pre = new ArrayDeque();
Deque<Integer> now = new ArrayDeque();
Deque tmp;
int n = 0, c = splitNum();
while (c >= '0' && c <= '9') {
pre.offer(c & 0xf);
c = getByte();
}
c = splitNum();
while (c >= '0' && c <= '9') {
n = n * 10 + (c & 0xf);
c = getByte();
}
while (n-- > 0) {
pre.offer(INF);
int nowV, preV = pre.poll(), len = 1;
do {
nowV = pre.poll();
if (nowV == preV) len++;
else {
now.offer(len);
now.offer(preV);
preV = nowV;
len = 1;
}
} while (nowV != INF);
if (n != 0) {
tmp = pre;
pre = now;
now = tmp;
now.clear();
}
}
while (!now.isEmpty())
out.print(now.poll());
out.close();
}
static byte[] buff = new byte[16];
static int next, blen;
static int getByte() {
if (next >= blen)
try {
next = 0;
blen = System.in.read(buff);
} catch (IOException e) {
e.fillInStackTrace();
}
return buff[next++];
}
static int splitNum() {
int c = getByte();
while (c < '0' || c > '9') c = getByte();
return c;
}
}
时间限制: 5.0s 内存限制: 512.0MB 本题满分: 77 分
问题描述
福尔摩斯从X星收到一份资料,全部是小写字母组成。
他的助手提供了另一份资料:许多长度为8的密码列表。
福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。
请你编写一个程序,从第一份资料中搜索可能隐藏密码的位置。要考虑密码的所有排列可能性。
输入格式
输入第一行:一个字符串s,全部由小写字母组成,长度小于1024*1024
紧接着一行是一个整数n,表示以下有n行密码,1<=n<=1000
紧接着是n行字符串,都是小写字母组成,长度都为8
输出格式
一个整数, 表示每行密码的所有排列在s中匹配次数的总和。
测试样例1
Input:
aaaabbbbaabbcccc
2
aaaabbbb
abcabccc
Output:
4
Explanation:
第一个密码匹配了3次,第二个密码匹配了1次,一共4次。
对它使用hash吧
先打个质数表
public class Test {
public static void main(String[] args) throws IOException {
int[] HASH_TABLE = new int[128];
HASH_TABLE['a'] = 2;
agent: for (int i = 'b', n = 3; i <= 'z'; n += 2) {
for (int k = 'a', g = (int)Math.sqrt(n); HASH_TABLE[k] <= g; k++)
if (n % HASH_TABLE[k] == 0) continue agent;
HASH_TABLE[i++] = n;
}
StringBuilder out = new StringBuilder("static final int[] HASH_TABLE = { ");
for (int i = 0; i < 128; i++)
out.append(HASH_TABLE[i] + ", ");
System.out.println(out.replace(out.length() - 2, out.length(), "};"));
}
}
code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class Main {
static final int[] HASH_TABLE = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101 };
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str = in.readLine();
if (str.length() < 8) {
System.out.print(0);
return;
}
Integer temp;
long cur = 1, cnt = 0;
int n = Integer.parseInt(in.readLine());
HashMap<Long, Integer> map = new HashMap();
while (n-- > 0) {
String line = in.readLine();
long key = 1;
for (int i = 0; i < 8; i++)
key *= HASH_TABLE[line.charAt(i)];
Integer val = map.get(key);
if (val == null) val = 0;
map.put(key, val + 1);
}
for (int i = 0; i < 7; i++)
cur *= HASH_TABLE[str.charAt(i)];
for (int i = 7, hi = str.length(); i < hi; i++) {
cur *= HASH_TABLE[str.charAt(i)];
temp = map.get(cur);
if (temp != null)
cnt += temp;
cur /= HASH_TABLE[str.charAt(i - 7)];
}
System.out.print(cnt);
}
}
时间限制: 8.0s 内存限制: 512.0MB 本题满分: 111 分
问题描述
蓝桥村的居民都生活在一条公路的边上,公路的长度为L,每户家庭的位置都用这户家庭到公路的起点的距离来计算,第i户家庭距起点的距离为di。
每年,蓝桥村都要举行一次集会。今年,由于村里的人口太多,村委会决定要在4个地方举行集会,其中3个位于公路中间,1个位最公路的终点。
已知每户家庭都会向着远离公路起点的方向去参加集会,参加集会的路程开销为家庭内的人数ti与距离的乘积。
给定每户家庭的位置di和人数ti,请为村委会寻找最好的集会举办地:p1, p2, p3, p4 (p1<=p2<=p3<=p4=L),使得村内所有人的路程开销和最小。
输入格式
输入的第一行包含两个整数n, L,分别表示蓝桥村的家庭数和公路长度。
接下来n行,每行两个整数di, ti,分别表示第i户家庭距离公路起点的距离和家庭中的人数。
输出格式
输出一行,包含一个整数,表示村内所有人路程的开销和。
测试样例1
Input:
6 10
1 3
2 2
4 5
5 20
6 5
8 7
Output:
18
Explanation:
在距起点2, 5, 8, 10这4个地方集会,6个家庭需要的走的距离分别为1, 0, 1, 0, 2, 0,总的路程开销为1*3+0*2+1*5+0*20+2*5+0*7=18。
评测用例规模与约定
对于10%的评测数据,1<=n<=300。
对于30%的评测数据,1<=n<=2000,1<=L<=10000,0<=di<=L,di<=di+1,0<=ti<=20。
对于100%的评测数据,1<=n<=100000,1<=L<=1000000,0<=di<=L,di<=di+1,0<=ti<=1000000。
code:
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
int n = in.nextInt(), l = in.nextInt();
House[] houses = new House[n + 1];
long[] buff = new long[n + 1];
for (int i = 0; i < n; i++)
houses[i] = new House(in.nextInt(), in.nextInt());
if (houses[n - 1].d == l) n--;
else houses[n] = new House(l, 0);
int mid = (int)find(0, n, buff, houses, true);
long res = find(0, mid, buff, houses, false) + find(mid + 1, n, buff, houses, false);
System.out.print(res);
}
static long find(int l, int r, long[] buff, House[] houses, boolean resType) {
int res = l;
long min = 0x3f3f3f3f3f3f3f3fL, leftV = 0, rightV = 0;
for (int i = l; i < r; i++)
rightV += buff[i] = (houses[r].d - houses[i].d) * houses[i].t;
for (int i = l; i < r; i++) {
leftV = 0;
rightV -= buff[i];
for (int j = i - 1; j >= l; j--)
leftV += (houses[i].d - houses[j].d) * houses[j].t;
if (min > (leftV += rightV)) {
min = leftV;
res = i;
}
}
return resType? res: min;
}
static class House {
int d, t;
House(int d, int t) {
this.d = d;
this.t = t;
}
}
static class InputReader {
private InputStream in;
private int next, len;
private byte[] buff;
InputReader(InputStream in) { this(in, 8192); }
InputReader(InputStream in, int buffSize) {
this.buff = new byte[buffSize];
this.next = this.len = 0;
this.in = in;
}
private int getByte() {
if (next >= len)
try {
next = 0;
len = in.read(buff);
if (len == -1) return -1;
} catch (IOException e) {
e.fillInStackTrace();
}
return buff[next++];
}
private int split() {
int c = getByte();
while (c <= 32 || c == 127) c = getByte();
return c;
}
public int nextInt() {
int n = 0, c = split();
boolean flag = true;
if (c == '-') {
c = getByte();
flag = false;
}
while (c >= '0'&& c <='9') {
n = n * 10 + (c & 0xf);
c = getByte();
}
return flag? n: -n;
}
}
}
先找到最优中点,然后折半枚举
这么做不大严谨但也不无道理
骗个三十分总可吧