目录
C:三国游戏
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
样例说明:
测评用例规模与约束:
个人思路:
个人代码:
D:平均
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
样例说明:
测评用例规模与约束:
个人思路:
个人代码:
E:填充
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
样例说明:
测评用例规模与约束:
个人思路:
个人代码:
F:棋盘
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
样例说明:
测评用例规模与约束:
个人思路:
个人代码:
普通差分:
二维差分:
G:子矩阵
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
样例说明:
测评用例规模与约束:
个人思路:
个人代码:
H:公因数匹配
问题描述:
输入格式:
输出格式:
样例输入:
样例输出:
测评用例规模与约束:
个人思路:
个人代码:
问题描述:
小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵 X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件,每个事件之 间相互独立且最多只会发生一次,当第 i 个事件发生时会分别让 X, Y, Z 增加 Ai , Bi ,Ci 。 当游戏结束时 (所有事件的发生与否已经确定),如果 X, Y, Z 的其中一个大 于另外两个之和,我们认为其获胜。
例如,当 X > Y + Z 时,我们认为魏国获 胜。小蓝想知道游戏结束时如果有其中一个国家获胜,最多发生了多少个事件? 如果不存在任何能让某国获胜的情况,请输出 −1 。输入格式:
输入的第一行包含一个整数 n 。
第二行包含 n 个整数表示 Ai,相邻整数之间使用一个空格分隔。
第三行包含 n 个整数表示 Bi,相邻整数之间使用一个空格分隔。
第四行包含 n 个整数表示 Ci,相邻整数之间使用一个空格分隔。
输出格式:
输出一行包含一个整数表示答案
样例输入:
3
1 2 2
2 3 1
1 0 7
样例输出:
2
样例说明:
发生两个事件时,有两种不同的情况会出现获胜方。
发生 1, 2 事件时蜀国获胜。
发生 1, 3 事件时吴国获胜。
测评用例规模与约束:
对于 40% 的评测用例,n ≤ 500 ;
对于 70% 的评测用例,n ≤ 5000 ;
对于所有评测用例,1 ≤ n ≤ 10^5,1 ≤ Ai , Bi ,Ci ≤ 10^9 。
按照题目要求,胜利条件为其中一方的积分大于另外两方积分之和
那么对于每一个事件而言,我们判定最终为A胜利的话,A在该事件中实际获得的积分为:
那么同理如下:
接下来我们从中选取X个事件,那么对应每一个的最终分值为:
如果有一方胜利需要满足下面三个条件中的任意一个:
因为题目要求的是最多的事件,那么我们对于每一个获胜的情况进行分开计算,通过贪心的方式(优先选取积分值高的),因此需要通过排序,然后遍历计算即可
import java.io.*;
import java.util.Arrays;
/**
* @ClassName 三国游戏
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 13:40
* @Version 1.0
**/
public class 三国游戏 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
int []a=new int[n];
int []b=new int[n];
int []c=new int[n];
for (int i=0;i=0;i--){
sum+=a[i];
ans+=b[i];
count+=c[i];
if (sum>0||ans>0||count>0) s=n-i;
}
pw.println(s);
pw.flush();
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}
问题描述:
有一个长度为 n 的数组(n 是 10 的倍数),每个数 ai 都是区间 [0, 9] 中的 整数。小明发现数组里每种数出现的次数不太平均,而更改第 i 个数的代价为 bi,他想更改若干个数的值使得这 10 种数出现的次数相等(都等于 n 10 ),请问 代价和最少为多少。
输入格式:
输入的第一行包含一个正整数 n 。
接下来 n 行,第 i 行包含两个整数 ai , bi ,用一个空格分隔。
输出格式:
输出一行包含一个整数表示答案
样例输入:
10
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
4 10
样例输出:
27
样例说明:
只更改第 1, 2, 4, 5, 7, 8 个数,需要花费代价 1 + 2 + 4 + 5 + 7 + 8 = 27 。
测评用例规模与约束:
对于 20% 的评测用例,n ≤ 1000;
对于所有评测用例,n ≤ 100000, 0 < bi ≤ 2 × 10^5 。
个人认为是严格意义上的签到题,对于0-9之间的每一个数都会出现n/10次,那么对于多出来的那部分出现次数进行更改即可,那么进行更改的情况一定会选择花费代价小的进行更改(贪心),因此只需要将给定数据进行二维排序即可
import java.io.*;
import java.util.Arrays;
/**
* @ClassName 平均
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 13:46
* @Version 1.0
**/
public class 平均 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
int [][]f=new int[n][2];
int []d=new int[10];
for (int i=0;i{
if (a[0]!=b[0]) return a[0]-b[0];
return a[1]-b[1];
}));
long sum=0;
for (int i=n-1;i>=0;i--){
d[f[i][0]]++;
if (d[f[i][0]]>n/10) sum+=f[i][1];
}
pw.println(sum);
pw.flush();
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}
问题描述:
有一个长度为 n 的 01 串,其中有一些位置标记为 ?,这些位置上可以任意 填充 0 或者 1,请问如何填充这些位置使得这个 01 串中出现互不重叠的 00 和 11 子串最多,输出子串个数。
输入格式:
输入一行包含一个字符串。
输出格式:
输出一行包含一个整数表示答案
样例输入:
1110?0
样例输出:
2
样例说明:
如果在问号处填 0 ,则最多出现一个 00 和一个 11:111000 。
测评用例规模与约束:
对于所有评测用例,1 ≤ n ≤ 1000000 。
这题还是相同的使用贪心思路,因为题目给定条件为:不重叠
那么我们从左往右开始判断每一个组合即可,遇到问号的就相当于万能改变,优先满足前面的可以更改的情况,如果前面的已经组合过了,那么?将与后一个进行组合
对于第一个符号为?的情况进行特殊比较即可
import java.io.*;
import java.util.Scanner;
/**
* @ClassName 填充
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 13:54
* @Version 1.0
**/
public class 填充 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
Scanner sc=new Scanner(System.in);
String ss=sc.nextLine();
boolean []f=new boolean[ss.length()+1];
int count=0;
for (int i=1;i
问题描述:
小蓝拥有 n × n 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了 m 次 操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反 (也就是白色棋 子变为黑色,黑色棋子变为白色)。请输出所有操作做完后棋盘上每个棋子的颜 色。
输入格式:
输入的第一行包含两个整数 n, m,用一个空格分隔,表示棋盘大小与操作 数。
接下来 m 行每行包含四个整数 x1, y1, x2, y2,相邻整数之间使用一个空格分隔,表示将在 x1 至 x2 行和 y1 至 y2 列中的棋子颜色取反。
输出格式:
输出 n 行,每行 n 个 0 或 1 表示该位置棋子的颜色。如果是白色则输出 0 ,否则输出 1 。
样例输入:
3 3
1 1 2 2
2 2 3 3
1 1 3 3
样例输出:
001
010
100
样例说明:
只更改第 1, 2, 4, 5, 7, 8 个数,需要花费代价 1 + 2 + 4 + 5 + 7 + 8 = 27 。
测评用例规模与约束:
对于 30% 的评测用例,n m ≤ 500 ;
对于所有评测用例,1 ≤ n, m ≤ 2000 ,1 ≤ x1 ≤ x2 ≤ n ,1 ≤ y1 ≤ y2 ≤ m 。
这是一个裸二维差分题,但是比赛的时候写的是普通一维差分+暴力,因为时间复杂度为O(n*m),不超时,怎么简单怎么来(但是赛时输出我中间用空格隔开,所以-15)
不了解的朋友可以查看这篇文章,个人觉得挺好:二维差分矩阵
import java.io.*;
/**
* @ClassName 棋盘
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 13:59
* @Version 1.0
**/
public class 棋盘 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
int m=nextInt();
int [][]f=new int[n+2][n+2];
for (int i=0;i
import java.io.*;
/**
* @ClassName 二维差分
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 14:10
* @Version 1.0
**/
public class 二维差分 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
int m=nextInt();
int [][]f=new int[n+2][n+2];
for (int i=0;i
问题描述:
给定一个 n × m (n 行 m 列)的矩阵。
设一个矩阵的价值为其所有数中的最大值和最小值的乘积。
求给定矩阵的 所有大小为 a × b (a 行 b 列)的子矩阵的价值的和。
答案可能很大,你只需要输出答案对 998244353 取模后的结果。
输入格式:
输入的第一行包含四个整数分别表示 n, m, a, b ,相邻整数之间使用一个空 格分隔。
接下来 n 行每行包含 m 个整数,相邻整数之间使用一个空格分隔,表示矩 阵中的每个数 Ai, j
输出格式:
输出一行包含一个整数表示答案
样例输入:
2 3 1 2
1 2 3
4 5 6
样例输出:
58
样例说明:
1 × 2 + 2 × 3 + 4 × 5 + 5 × 6 = 58 。
测评用例规模与约束:
对于 40% 的评测用例,1 ≤ n, m ≤ 100 ;
对于 70% 的评测用例,1 ≤ n, m ≤ 500 ;
对于所有评测用例,1 ≤ a ≤ n ≤ 1000 1 ≤ b ≤ m ≤ 1000 1 ≤ Ai, j ≤ 10^9 。
这是个优先队列的题,但是优先队列写的比较少,不太能盲写,所以写了一个O(n*m^2)复杂度的方式,不过在C语言网上测试为通过,官方数据应该过70%+
我们先将每一行需要的个数提取,即输入中的a行b列中的b,然后我们从每一行的第b-1个开始计算每一行这个位置的最大值与最小值,然后同理,判断每一列的,但是在每一列的时候,我们可以直接从第a-1行,b-1列开始,用a*b大小的矩阵中已知的每一行的最大最小,通过最终的那一列进行判断即可
import java.io.*;
/**
* @ClassName 子矩阵
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/10 23:47
* @Version 1.0
**/
public class 子矩阵 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
int m=nextInt();
int a=nextInt();
int b=nextInt();
int [][][]f=new int[n][m][3];
for (int i=0;i=i-a+1;k--){//往上推,通统计这a行的数的最大最小
max=Math.max(max,f[k][j][2]);
min=Math.min(min,f[k][j][1]);
}
sum+=((long)max*min)%998244353;//求和
sum%=998244353;
}
}
pw.println(sum);
pw.flush();
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}
问题描述:
给定 n 个正整数 Ai,请找出两个数 i, j 使得 i < j 且 Ai 和 Aj 存在大于 1 的 公因数。
如果存在多组 i, j,请输出 i 最小的那组。如果仍然存在多组 i, j,请输出 i 最小的所有方案中 j 最小的那组
输入格式:
输入的第一行包含一个整数 n。
第二行包含 n 个整数分别表示 A1 A2 · · · An,相邻整数之间使用一个空格 分隔。
输出格式:
输出一行包含两个整数分别表示题目要求的 i, j,用一个空格分隔。
样例输入:
5
5 3 2 6 9
样例输出:
2 4
测评用例规模与约束:
对于 40% 的评测用例,n ≤ 5000 ;
对于所有评测用例,1 ≤ n ≤ 10^5,1 ≤ Ai ≤ 10^6 。
用map去存储每一个>1的因子第一次出现的位置,如果后续的数字出现了该因子,则按照题目要求去进行更改,时间复杂度为O()
注意,在判断的时候需要判断这个数的因子下标与当前位置不同,且当前数值>1也应当属于因子,去进行特殊判定
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName 公因数匹配
* @Description TODO
* @Author 小怂很怂
* @Date 2023/4/8 14:24
* @Version 1.0
**/
public class 公因数匹配 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n=nextInt();
Map map=new HashMap<>();
int min=99999999,max=0;
int r=min,l=0;
for (int i=0;i
9/10两题没机会AC,没有AC思路,所以就到这吧
总的而言今年的JavaC题目没去年难的感觉,当然其他组比如JavaB,C++B,C++C这些组都挺难的,去的话估计爆0了,还是javac适合新手