这是腾讯机试的第二场,还是五道编程题,通过率 80%,40%,100%,没做,0%
题目一
小Q玩游戏,最开始有n个人参与,编号 1-n ,坐成一个圆,并从一号依次报数,最后一个同学报数之后一号同学继续报数,在每一轮游戏中,第m个报数的玩家会被淘汰,之后将有数个同学上场,依次坐在被淘汰同学的位置上,并顺次编号,之后由替补上场的第一个同学开始报数,开始下一轮游戏,游戏进行k轮。
输入:
第一行三个数字 ,n,m,k,分别表示游戏初试人数,每一轮报数的玩家数量,游戏的轮数。之后的一行数字将包含n个数字 Pi (1<= i <= n),代表每轮游戏结束后替补上场玩家个数。
输出:
输出n行,代表每一轮游戏被淘汰的玩家编号。
输入:
4 3 3
2
1
3
输出;
3
4
2
说明:一开始 1 2 3 4 淘汰3 ,加入两名玩家,变成 1 2 5 6 4,从5开始,淘汰4,加入7 ,1 2 5 6 7,从7开始报数,淘汰2,加入三名玩家,变成 1 8 9 10 5 6 7 ,游戏结束
题目分析:
我是做的模拟循环链表的操作。
代码实现:
//80%
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int k = in.nextInt();
int input[] = new int[k];
for (int i = 0; i < k; i++)
input[i] = in.nextInt();
Node head = new Node(1);
Node head1 = head;
for (int i = 2; i <= n; i++) {
Node temp = new Node(i);
head.next = temp;
head = head.next;
}
head.next = head1;
int time = 0;
while (time < k) {
for (int i = 0; i < m - 2; i++) {
head1 = head1.next;
}
Node nownext = head1.next.next;
Node now = head1;
System.out.println(head1.next.val);
for (int i = 0; i < input[time]; i++) {
Node temp = new Node(++n);
now.next = temp;
now = now.next;
}
now.next = nownext;
head1 = head1.next;
time++;
}
}
static class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
第二题
小Q在每一个期末的时候,都会对本学期学习的情况做一次全面的总结,如果这学期有n天,那么小Q会对每一天打一个分,他对一段时间学习状态的评分为这段时间学习状态最低的分数与这段时间学习状态分数之和的乘积,小Q想知道他这个学期中学习状态评分最高的时间段评分是多少?
输入:
输入第一行将包含一个数字n,代表本学期的天数,接下来一行包含n个数字Wi,代表每一天的学转态分步。
1 <= n <= 100000;
1 <= Wi <= 100000;
输出描述:
输出一个数字,代表小Q在这个学期中学习状态评分最高的时间段评分。
示例输入:
5
7 2 4 6 5
示例输出:
60
说明:
选择3 - 5 天,学习状态最低分4,和是15,乘积60.
题目分析:
我是用的暴力破解,只过了40;感觉明显是超时了,但是因为累加会超过int.max,所以必须至少用long。
代码实现:
//40%
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int input[] = new int[n];
double Max = 0;
for (int i = 0; i < n; i++)
input[i] = in.nextInt();
long x[] = new long[n];
Arrays.fill(x, 0);
x[0] = input[0];
for (int i = 1; i < n; i++) {
x[i] = input[i] + x[i - 1];
}
for (int i = 1; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
Max = Math.max(Max, (double) input[findmin(input, i, j)] * (double) (x[j] - x[i - 1]));
}
}
System.out.printf("%.0f", Max);
}
public static int findmin(int[] input, int head, int wear) {
int min = 100001;
int local = 0;
for (int i = head; i <= wear; i++) {
if (input[i] < min) {
min = input[i];
local = i;
}
}
return local;
}
public static long getall(int[] input, int head, int wear) {
long val = 0;
for (int i = head; i <= wear; i++) {
val += (long) input[i];
}
return val;
}
}
第三题
排队时候,n个顾客,编号 1-n ,每个人都有两个属性ai 和 bi,每个人的不满意度 等于站在他前面的人数 * ai+站在他后面的人数 * bi。假使位置是j,既 aj * (j - 1)+ bi *(n - j)。
要求对顾客进行重新排序,使得总的不满意度最小。
输入描述:
第一行一个整数n,表示顾客的数量;
接下来 n 行,第 i 行包含两个整数 ai 和 bi,用一个空格分隔;
输出描述:
一个整数,表示总和。
示例输入1:
2
1 1
2 2
示例输出1:
3
示例输入2:
3
1 3
1 1
4 1
示例输出1:
6
题目分析:
咋一看感觉题目很复杂,但是经过公示化简发现,每个人的不满意度 = (ai - bi)* i + (n -i) * bi 。
只需要对(ai - bi) 进行排序即可。
代码实现:
//AC
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int mat[][] = new int[n][2];
int[] b = new int[n];
for (int i = 0; i < n; i++) {
mat[i][0] = in.nextInt();
mat[i][1] = in.nextInt();
b[i] = mat[i][0] - mat[i][1];
}
Arrays.sort(b);
for (int i = 0; i < n / 2; i++) {
int temp = b[i];
b[i] = b[n - 1 - i];
b[n - 1 - i] = temp;
}
long result = 0;
for (int i = 0; i < n; i++) {
result += (long) b[i] * i + (long) (n - 1) * mat[i][1];
}
System.out.println(result);
}
}
后面两个题没有做出来,就不写了。