360技术笔试编程题
写在前面
360技术笔试编程题
前面的选择题各式各样,感觉都答懵了所以编程题时间就不够了,这个真是经验之谈,以后还是先做编程,再做选择。。。再多几分钟,就能调出来。。摔杯啊~~~所以像我这种的,最后只是写上去,第二题提交的还有包名,估计编译都不过。。。。以后笔试先做编程,先编程,先编程。重要的事情说三遍。
好了 正题开始。
1、第一题
题目描述
为考验各自的数学能力,小B和小A经常在一起玩各种数值游戏,这一次他们又有了一种新玩法。每人从指定的数值范围中各自选择一个整数,记小A选择的数值为a,小B选择的数值为b。他们用一个均匀分布的随机数发生器在该数值范围中随机生成一个整数c,定义制胜的游戏规则为谁选的数离c近则谁取得胜利。由于小B是女生,特别定义当两人的数与c之间的差值相等时,小B获胜。
由于先前的游戏中,小A为表现绅士风度总是输多赢少,因此他特别渴望这次能够给小B比较深刻的映像,所以向你求助。你事先已经知道了小B所选的数值和指定的数值范围,小A希望你帮他选择一个数值使得他获胜的概率最大。
输入多行,每行一组数据,包含两个正整数n和b,分别代表数值范围和小B所需的数字,其中 1 <= b <= n <= 10^9.
每组输入,单独的行中输出一个数,为小A所选的数字,使得小A获胜的概率最大,若存在多个这样的数,输出最小的那个。
题目分析
这个题其实不难,但题意半天搞不懂,所以开始试了几次都错误。
显然看出,小A不一定赢,因为假设两人都猜对,那也是小B获胜。所以其实本题就是求出在所有情况下,小A获胜概率最大的数,更直白的说,小A猜数结果从1到n,有n种情况,猜哪个数字使得获胜概率最大。而只要小A猜测的结果比小B更接近c,就是获胜。
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int n = cin.nextInt();
int b = cin.nextInt();
int max = 0;
int index = 0;
for (int i = 1; i <= n; i++) { // 列举小A的选择求出,该选择下对应的获胜情况,
int win = 0; // 小A选择i,随机数为任意情况下小B获胜大小
for (int c = 1; c <= n; c++) {
if (Math.abs(c - i) < Math.abs(c - b)) // 小A获胜
win++;
}
if (win > max) {
max = win;
index = i;
}
}
System.out.println(index);
}
cin.close();
}
}
讨论
评论区有人回复说用简单的数学方法。就是说,给定区间1~n,判断小B取值在中位数的哪侧,也就是说,如果小B取值在中位数右侧,那小A只要取值为小B取值数-1,反之,如果小B取值在中位数左侧,那小A只要取值为小B取值数+1。更具体地说:
情况一:如果小B取值在中位数右侧,随机数的取值为1~n,所以如果小A只要取值为B-1,那么随机数分布在小B左侧的情况下,小A赢。(因为左侧明显多嘛)
反之。
代码比较简单,判断和中位数的大小。然后输出。
2、第二题
题目描述
小B最近迷上了字符串处理技术,他设计了各种处理方式,并计算字符串的属性。这次也不例外,他定义了一种新的字符置换方式。小B研究的字符串由ASCII码字母和“.”构成,这次的研究对象是“.”。他关心的对象是字符串中出现的连续两个“.”。若每次操作把其中最开始的连续两个“.”以一个“.”替代,则可以将函数f(s) 定义为使得串中不出现连续两个“.”的最小置换次数。
现考虑m个字符替换操作,每次将指定位置的字符替换为给定的字符,求替换后函数f(s)的值。
输入有若干行,没组的第一行为两个整数n和m,1 <= n, m <= 300000,表示字符串的长度和字符串替换操作的次数,第二行为所给的字符串,随后紧跟着m行操作,每行由一个正整数x和一个字母c组成,表示将字符串位置m出的字符置换为字母c。
输出:对每组输入的每个置换操作,在单独的行中输出函数f(s)的结果。
题目分析
题目的关键是函数f(s)的实现。
一个连续“.”,返回0;
两个连续“.”,返回1;
三个连续“.”,返回2;
四个连续“.”,返回3;
...
所以规律就是有n个连续“.”,返回n-1;
这个题目我卡在字符串处理上,你敢信,一种就是像我下面写的这种方法,另一种就是可以转换为字符数组,然后进行处理。
下面这个版本我本机测试通过
import java.util.Scanner;
public class Main {
public static int dealString(String str) {
int left1 = str.indexOf('.'), left2 = left1;
int count = 0;
while (left1 < str.length() && left2 < str.length()) {
if (str.charAt(left2) == '.') {
while (left2 < str.length() && str.charAt(left2) == '.')
left2++;
int tmp = left2 - left1 - 1;
count += tmp;
}
if (left2 < str.length() && str.charAt(left2) != '.') {
left2++;
left1 = left2;
}
}
return count;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int n = cin.nextInt();
int m = cin.nextInt();
String str = cin.next();
for (int i = 1; i <= m; i++) {
int index = cin.nextInt();
String ch = cin.next();
String tmp = "";
if (index > 1)
tmp = str.substring(0, index - 1);
str = tmp + ch + str.substring(index);//替换字符
int count = dealString(str);
System.out.println(count);
}
}
cin.close();
}
}
如果有更好的解决办法,欢迎大家一起讨论。