emm
记录一下题目
1.最差运气
有一款游戏,过关的方式是按按钮。
游戏一共有1关,每一关有个按钮,其中只有唯一—个按钮是可以通关的,按下其他的按钮游戏就会失败。
好在这个游戏可以重来,而且由于设计者的疏忽,每一关的通关按钮是不变的,所以你可以记住前几关的按钮,重来时就可以直接通关。
但是…你的运气似乎用在了其他地方,你使用了最多的按按钮次数才成功通关。
求这个最多的按按钮次数吧!
思路:普通计算,理清逻辑,一步一步往下写,先求失败次数,再求最后通过次数
//核心代码模式
public long findMaxButtons(int[] a)
{
long res = a.length; //最后通过时按下的次数
for(int i = 0; i < a.length ; i++)
{
res += (long) (a[i] - 1) * i; //累加失败次数:第i关失败a[i] - 1次,每次都要按i次按钮
}
return res;
}
2. 刷墙
最近小明搬到了新家,他正在粉刷墙壁,但是不幸的是他粉刷的墙壁并不理想。他的墙壁是一个长度为n的格子,每个格子用0表示红色,用1表示蓝色。现在墙壁是一个非常混乱的颜色。他想将墙壁涂成左边全是蓝色右边全是红色,可以将墙壁刷成全是红色或者蓝色。请问他至少需要粉刷多少个格子墙壁刷成他想要的样子?
思路: 枚举 + 前缀和
枚举所有情况,选择最少次数(暴力方法)
使用前缀和进行优化(预处理减少重复计算次数)
前缀和:在经过一次O(n)的预处理后,可以以O(1)查询目标区间的和
import java.util.Scanner;
public class Main{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
//获取输入
int n = in.nextInt();
String str = " " + in.next();
int[] sum = new int[n+1];
for(int i = 1; i <= n; i++)
{
sum[i] = sum[i-1] + s.charAt(i) - '0';
}
//枚举所有边界情况,寻找最小值
int res = n; //找最小,初始化最大
for(int i = 0; i <= n; i++) //注意,从0-n
{
//[1, i]中0的个数: i - sum[i]
//[i+1 , n]中1的个数: sum[n] - sum[i]
res = Math.min(res , i - sum[i] + sum[n] - sum[i]);
}
//输出
System.out.println(res);
}
}
3.胜者为王
小明,小王,小李三人正在进行一个游戏。游戏有n个回合,每个人都有一个字符串,三人的字符串长度相等。每个回合他们必须更改自己字符串中的一个字母。最后每个人的分数是字自己的字符串中出现字符最多的字母的数量。分数最高者获胜,输出获胜者名字,小明获胜输出xiaoming,小王获胜输出xiaowang,小李获胜输出xiaoli,如果有两个或者两个以上相同的最高分输出draw。
思路:贪心思想:对于每个回合分配到的字符串,每次更改其他字符为出现次数最多的字符 ,
设出现最多字符为x,n回合,则分数 = min(x + n , len);
//考虑一种情况:如果 x + n > 字符串长度,会不会必须反转x : 不必,只需不断更新最后一个字符为其他字符,在最后一个回合更换为x,因此,分数最大为字符串长度
//编码实现
import java.util.Scanner;
public class Main{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String s1 = in.nextLine();
String s2 = in.nextLine();
String s3 = in.nextLine();
int len = s1.length();
int x = 0, y = 0 , z = 0; //对应s1, s2, s3
//计算s1中字符出现的最多次数
int[] cnt = new int[256];
for(int i = 0; i < len; i++)
x = Math.max(x , ++cnt[s1.charAt(i)]); //char自动转型为int
for(int i = 0; i < 256; i++)
cnt[i] = 0; //清0,重复利用数组空间
//计算s2
for(int i = 0; i < len; i++)
y = Math.max(y , ++cnt[s2.charAt(i)]);
for(int i = 0; i < 256; i++)
cnt[i] = 0;
//计算s3
for(int i = 0; i < len; i++)
z = Math.max(z , ++cnt[s3.charAt(i)]);
for(int i = 0; i < 256; i++)
cnt[i] = 0;
//计算n回合得分
x = Math.max(x + n , len);
y = Math.max(y + n , len);
z = Math.max(z + n , len);
//输出结果
if(x > y && x > z)
System.out.println("xiaoming");
else if(y > x && y > z)
System.out.println("xiaowang");
else if(z > x && z > y)
System.out.println("xiaoli");
else
System.out.println("draw");
}
}
本文介绍了两个有趣的编程挑战:一是通过不断尝试找到游戏中的通关按钮;二是计算将一面混杂颜色的墙重新粉刷所需的最少操作次数。文章提供了详细的算法思路及实现代码。



523

被折叠的 条评论
为什么被折叠?



