“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情”
第一题
题目理解
有若干个被选中的运动员参与了5场马拉松,给出他们的排名,然后给出比较运动员的成绩优劣的依据:若运动员甲在5场比赛中至少有3场的名次高于运动员乙,那么甲就优于乙。题目要求我们找出成绩能优于其他被选中的运动员的那个运动员
输入
输入整数,代表案例个数,
每个案例第1行输入1个整数,
每个案例的第二行到第行输入5个整数:表示这若干个运动员参加这五场比赛所获得的名次
输出
每个案例输出一个整数——代表找出的最优的运动员(找不到最优者则输出-1)
思路代码
一般的模拟思路,就是用一个运动员作为“擂主”逐个去与其他运动员比较,不是最优者则换一个“擂主”,这样做的话最坏的情况下每个运动员都得当一次“擂主”,时间复杂度很高,会出现超时。要对模拟方法进行优化,那就要知道这个思路其实是分两步的,一步是找“擂主”,下一步是与其他人相比较。我们其实可以在找“擂主”上简单一点:先定一个人为“擂主”,若有优于这个人的则换更优者当擂主,这样若存在真正的最优者,最后的“擂主”一定会是他,但未必所有的赢到最后的人就是最优者,所以要再把“擂主”与其他人比较确认一遍。
import java.util.Scanner;
public class Run_for_gold {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();//读取输入
for (int i = 0; i < t; i++) {
int n=sc.nextInt();
int[][] r=new int[n][5];
for(int j=0;j<n;j++) {
for (int k=0;k<5;k++) {
r[j][k]=sc.nextInt();//读取输入
}
}
if(n==1) {//特殊情况:“无敌是多么寂寞”
System.out.println(1);
continue;
}
int zf=0;
int best=0;
//找出“擂主”
for(int j=0;j<n;j++) {
for (int k = 0; k < 5; k++) {
if(r[j][k]<r[best][k])
zf++;
else if(r[j][k]>r[best][k])
zf--;
}
if(zf>0)
best=j;
zf=0;
}
//确认“擂主”是不是最优者
int superior=0;
for(int j=0;j<n;j++) {
for (int k = 0; k < 5; k++) {
if(r[j][k]<r[best][k])
zf++;
else if(r[j][k]>r[best][k])
zf--;
}
if(zf>0)
superior--;
else if(zf<0)
superior++;
zf=0;
}
int ans=-1;
if(superior==n-1) {
ans = best + 1;
}
System.out.println(ans);
}
}
}
第二题
题目理解
给出一个长度为的只含有0或者1的字符串,以及两个参数和,给出前提如下:
- 要把这个字符串里面的所有字符都删除
- 对删除操作有限制,每一次删除只能删除若干(这个可以自己定)个相同的字符(比如删除111和00)
- 删除一个长度为的字符串就会得到分
- 求出要达到要求所能得到的最多分数
输入
输入整数,代表案例个数,
每个案例第1行输入1个整数,
每个案例的第二行输入一个长度为的字符串
输出
每个案例输出一个整数——代表能得到的最高分
思路
通过对删除过程以及删除操作的模拟我们发现:在不同的删除操作次数的情况下,参数对于得分情况的影响是相同的,而参数对得分的影响则很大。若参数为正,则删除次数肯定是越多越好,为负则反之。那么我们现在就只需要考虑如何使删除次数达到最少。要达到最少的话那就需要一次尽可能删除足够多的字符,那么我们这里可以稍微用一下贪心的思想:若把0或者1的其中一类全删了,然后再用一次删掉另一类,这是不是最少的呢?起码在测试了多种样例之后确实如此。
import java.util.Scanner;
public class Maximum_Cost_Deletion {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
int n=sc.nextInt();
int a=sc.nextInt();
int b=sc.nextInt();
String s=sc.next();
if(b>=0)
{
System.out.println(n*(a+b));
}
else {
char[] x=s.toCharArray();
char temp='x';//随便定个不是‘0’或‘1’的字符
int count0=0;
int count1=0;
for(int j=0;j<n;j++)//找出0和1的段数
{
if(x[j]!=temp&&x[j]=='1')
{
temp=x[j];
count1++;
}
else if(x[j]!=temp&&x[j]=='0')
{
temp=x[j];
count0++;
}
}
int count=count0>count1?count1:count0;
int ans=(count+1)*b+n*a;
System.out.println(ans);
}
}
}
}