CCF签到题,没有提到分数的题目都是100分,不然会额外提出,样例输入都单独文本复制粘贴了,这样你们测试的时候很方便粘贴用例,不用自己手敲,都是一些签到题。但有好的基础,会多的数据结构,好的数学思想,那么这些都是一些很简单的问题。因为java版本不多,所以仅供参考,以下代码的思路都很简单,很多都直接通过题目面向过程,有更好的想法,或者你我有些题没有满分的改进方式都可以交流。
CCF300分的线,1、2题需要拿满,最低也要190,第三题是理解题,很多时候考你的语文能力更多,第四题是规律性更强的题,涉及图论算法众多(最小生成树3题,通信网络,最优灌溉,数据中心,地铁修建)(最短路径4题,最优匹配,无线网络,交通规划,游戏)(欧拉图,强连通分支,最长路径也都考过),还有正则匹配的题(5题url映射,json查询,markdown,模板生成系统,字符中匹配),总而言之一句话,第4题规律性很强。你只需要1、2题拿满,第4题拿90,第五题和第三题通过理解之后,暴力得分,就能稳300分以上,不排除某年的题会难、杂,或者当年当月你不在巅峰,那就下一次再考,上面列举的题型出现的频率极高,针对1、2、4刷题性价比是最高的。
下面只提供了第一题和第二题,因为在线测试对java语言不太友好,导致我的3、4题分数参差不齐,所以没有提供代码,网上有众多优秀的博客,输入试题编号和名称即可找到,看看思路,自己再写一遍,算法之路,任重道远。(数学很重要,数学是编程的降维武器)
试题编号:201312-1
试题名称:出现次数最多的数
样例输入
6
10 1 10 20 30 20
样例输出
10
思路:解决方法有很多,要么空间够大开够,用下标去加加计数,或者用hashset一直塞,重复会返回default,然后default就对应加加,用indexof找,唯一值,还可以用一个数组,在插入时注意排序,因为需要输出最小值,插入时就排好序,重复的就加加次数,总之方法很多。
importjava.util.Scanner;public classCCF201312_1 {public static voidmain(String[] args) {
Scanner sc=newScanner(System.in);int n=sc.nextInt();int[] space=new int[n];for(int i=0;i
space[i]=sc.nextInt();
}int[] flag=new int[10000];for(int i=0;i
flag[space[i]]++;
}int max=0;int index=0;int finded=0;for(int i=0;i<10000;i++) {if(flag[i]!=0) {
finded=finded+flag[i];
}if(flag[i]>max) {
max=flag[i];
index=i;
}if(finded==n) {break;
}
}
System.out.println(index);
}
}
试题编号:201312-2
试题名称:ISBN号码
样例输入
0-670-82162-0
样例输出
0-670-82162-4
思路:问题描述中已经有具体步骤了,对于格式统一,下标固定的问题,基本数据结构掌握就可以解决。
importjava.util.Scanner;public classCCF201312_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);
String sourse=sc.nextLine();int ret = 1 * (sourse.charAt(0) - '0') + 2 * (sourse.charAt(2) - '0') + 3 * (sourse.charAt(3) - '0')+ 4 * (sourse.charAt(4) - '0') + 5 * (sourse.charAt(6) - '0') + 6 * (sourse.charAt(7) - '0')+ 7 * (sourse.charAt(8) - '0') + 8 * (sourse.charAt(9) - '0') + 9 * (sourse.charAt(10) - '0');
ret= ret % 11;if (sourse.charAt(12) == 'X') {//如果默认为X
if (ret == 10) {//匹配对
System.out.print("Right");return;
}else {//不匹配
for (int i = 0; i < sourse.length() - 1; i++) {
System.out.print(sourse.charAt(i));
}
System.out.print(ret);
}
}else {//默认不是X
if ((sourse.charAt(12) - '0') ==ret) {
System.out.print("Right");return;
}if (ret == 10) {for (int i = 0; i < sourse.length() - 1; i++) {
System.out.print(sourse.charAt(i));
}
System.out.print("X");return;
}else{for (int i = 0; i < sourse.length() - 1; i++) {
System.out.print(sourse.charAt(i));
}
System.out.print(ret);
}
}
}
}
试题编号:201403-1
试题名称:相反数
样例输入
5
1 2 3 -1 -2
样例输出
2
思路:给了范围,不会超过一千,用二维数组,正负分开在二维数组上加加,然后判断有多少对即可,用finded去记录找到的数目,可以提前退出循环,提高速度。
importjava.util.Scanner;public classCCF201403_1 {public static voidmain(String[] args) {
Scanner sc=newScanner(System.in);int N=sc.nextInt();int[] sourse=new int[N];int[][] flag=new int[1000][2];for(int i=0;i
sourse[i]=sc.nextInt();if(sourse[i]>0) {
flag[sourse[i]][1]++;
}else{
flag[-1*sourse[i]][0]++;
}
}int finded=0;int count=0;for(int i=0;i<1000;i++) {if(flag[i][0]>0||flag[i][1]>0) {
finded+=flag[i][0]+flag[i][1];
}if((flag[i][0]>flag[i][1])&&(flag[i][1]>0)) {
count+=flag[i][1];
}if((flag[i][1]>flag[i][0])&&(flag[i][0]>0)) {
count+=flag[i][0];
}if((flag[i][1]==flag[i][0])&&flag[i][1]>0) {
count+=flag[i][0];
}if(finded==N) {break;
}
}
System.out.println(count);
}
}
试题编号:201403-2
试题名称:窗口
样例输入
3 4
0 0 4 4
1 1 5 5
2 2 6 6
1 1
0 0
4 4
0 5
样例输出
2
1
1
IGNORED
样例说明
第一次点击的位置同时属于第 1 和第 2 个窗口,但是由于第 2 个窗口在上面,它被选择并且被置于顶层。
第二次点击的位置只属于第 1 个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。
第三次点击的位置同时属于三个窗口的范围,但是由于现在第 1 个窗口处于顶层,它被选择。
最后点击的 (0, 5) 不属于任何窗口。
思路:这题有点意思,但是题目中告诉你窗口是自下向上给出,而窗口在上方的又具有更高的优先级,所以用数组存取每一层窗口的坐标,下标越高的窗口优先级就越高,从后往前遍历,看chick的点是否在当前层之内,如果在就输出,并且用newone函数去把当前窗口的级别调整到最高,也就是向数组的最后部推,这样优先级即为最高,实现比较器会比较方便交换,这里直接用temp值交换了。
importjava.util.Scanner;public classCCF201403_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int N =sc.nextInt();int M =sc.nextInt();int[][] Sourse = new int[N][5];for (int i = 0; i < N; i++) {
Sourse[i][0] =sc.nextInt();
Sourse[i][1] =sc.nextInt();
Sourse[i][2] =sc.nextInt();
Sourse[i][3] =sc.nextInt();
Sourse[i][4]=i+1;
}int[][] chick = new int[M][2];for (int i = 0; i < M; i++) {
chick[i][0] =sc.nextInt();
chick[i][1] =sc.nextInt();
}int key = 0;for (int i = 0; i < M; i++) {intj;for (j = N - 1; j >= 0; j--) {if ((Sourse[j][0] <= chick[i][0]) && (chick[i][0] <= Sourse[j][2]) && (Sourse[j][1] <= chick[i][1])&& (chick[i][1] <= Sourse[j][3])) {
System.out.println(Sourse[j][4]);
Sourse=newOne(Sourse, j);break;
}
}if (j == -1) {
System.out.println("IGNORED");
}
}
}public static int[][] newOne(int[][] Sourse, intkey) {int n = Sourse.length - 1;int tempX1 = Sourse[key][0];int tempY1 = Sourse[key][1];int tempX2 = Sourse[key][2];int tempY2 = Sourse[key][3];int tempIndex=Sourse[key][4];for (int i = key; i < n; i++) {
Sourse[i][0] = Sourse[i + 1][0];
Sourse[i][1] = Sourse[i + 1][1];
Sourse[i][2] = Sourse[i + 1][2];
Sourse[i][3] = Sourse[i + 1][3];
Sourse[i][4] = Sourse[i + 1][4];
}
Sourse[n][0] =tempX1;
Sourse[n][1] =tempY1;
Sourse[n][2] =tempX2;
Sourse[n][3] =tempY2;
Sourse[n][4]=tempIndex;returnSourse;
}
}
试题编号:201409-1
试题名称:相邻数对
样例输入
6
10 2 6 3 7 8
样例输出
3
样例说明
值正好相差1的数对包括(2, 3), (6, 7), (7, 8)。
评测用例规模与约定
1<=n<=1000,给定的整数为不超过10000的非负整数。
思路:因为数值最大为10000,但要考虑重复的情况,第一题一般对时间空间没有什么要求,用下标去加加计数,然后通过循环去获取相邻差为1的整数对,用finded去对找到的点进行计数提前退出,然后去找连续的重复值加到ret上即可。
importjava.util.Scanner;public classCCF201409_1 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[] sourse = new int[n];int[] space = new int[10000];for (int i = 0; i < n; i++) {
sourse[i]=sc.nextInt();
space[sourse[i]]++;
}int ret = 0;int finded = 0;for (int i = 0; i < 9999; i++) {if (space[i] > 0) {
finded+=space[i];if (space[i + 1] > 0) {
ret+= space[i + 1];
}
}if (finded ==n) {break;
}
}
System.out.println(ret);
}
}
试题编号:201409-2
试题名称:画图
样例输入
2
1 1 4 4
2 3 6 5
样例输出
15
评测用例规模与约定
1<=n<=100,0<=横坐标、纵坐标<=100。
思路: 简单的遍历,涂色,网络上还有逆向思路的,去计算最大正方形,然后扣空,但不易操作,所以通过开辟空间使问题简单化
importjava.util.Scanner;public classCCF201409_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[][] space = new int[n][4];int minX = 100;int maxX = 0;int minY = 100;int maxY = 0;for (int i = 0; i < n; i++) {
space[i][0] =sc.nextInt();if (space[i][0]
minX= space[i][0];
}
space[i][1] =sc.nextInt();if (space[i][1]
minY= space[i][1];
}
space[i][2] =sc.nextInt();if (space[i][2] >maxX) {
maxX= space[i][2];
}
space[i][3] =sc.nextInt();if (space[i][3] >maxY) {
maxY= space[i][3];
}
}int[][] color = new int[maxX - minX][maxY -minY];for (int i = 0; i < n; i++) {for (int j = space[i][0] - minX; j < space[i][2] - minX; j++) {for (int k = space[i][1] - minY; k < space[i][3] - minY; k++) {
color[j][k]++;
}
}
}int ret = 0;for (int i = 0; i < maxX - minX; i++) {for (int j = 0; j < maxY - minY; j++) {if (color[i][j] > 0) {
ret++;
}
}
}
System.out.println(ret);
}
}
试题编号:201412-1
试题名称:门禁系统
样例输入
5
1 2 1 1 3
样例输出
1 1 2 3 1
评测用例规模与约定
1≤n≤1,000,读者的编号为不超过n的正整数。
思路:很水的题,直接边读边输出就行了。
importjava.util.Scanner;public classCCF201412_1 {public static voidmain(String[] args) {
Scanner sc=newScanner(System.in);int n=sc.nextInt();int[] array=new int[1000];for(int i=0;i
System.out.println(++array[sc.nextInt()]);
}
}
}
试题编号:201412-2
试题名称:Z字形扫描
样例输入
4
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
样例输出
1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
评测用例规模与约定
1≤n≤500,矩阵元素为不超过1000的正整数。
思路:也是一道比较有意思的题,但是找到规律之后也很简单,首先分奇偶,然后把拐角的点和直线的点都写出来,就发现出现的情况是一定对称的,不论奇偶都是对称的,拐点是周期性循环变化,拐弯之后的直线周期性增加,当到对角线时操作最长为y,不理解的同学可以把过程的点都写出来,然后在这些点之间,把x++,或y++的变化过程标上去,就一目了然了。最后不要忘记特殊情况的处理。还理解不了的可以结合着图,并且通过debug模式去一步一步的推算,规律题。
importjava.util.Scanner;public classCCF201412_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[][] Z = new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {
Z[i][j]=sc.nextInt();
}
}if (n == 1) {
System.out.print(Z[0][0]);return;
}if (n == 2) {
System.out.print(Z[0][0] + " " + Z[0][1] + " " + Z[1][0] + " " + Z[1][1]);return;
}int x = 0;int y = 0;int flag = 1;int choose = 1;
System.out.print(Z[x][y]+ " ");
choose= -1;while (flag !=n) {if (choose == -1) {
System.out.print(Z[x][++y] + " ");for (int i = 0; i < flag; i++) {
System.out.print(Z[++x][--y] + " ");
}
choose= 1;
}else{
System.out.print(Z[++x][y] + " ");for (int i = 0; i < flag; i++) {
System.out.print(Z[--x][++y] + " ");
}
choose= -1;
}
flag++;
}
flag--;
flag--;
choose= choose * -1;while (flag != 0) {if (choose == -1) {
System.out.print(Z[x][++y] + " ");for (int i = 0; i < flag; i++) {
System.out.print(Z[--x][++y] + " ");
}
choose= 1;
}else{
System.out.print(Z[++x][y] + " ");for (int i = 0; i < flag; i++) {
System.out.print(Z[++x][--y] + " ");
}
choose= -1;
}
flag--;
}
System.out.print(Z[x][++y]);
}
}
试题编号:201503-1
试题名称:图像旋转
样例输入
2 3
1 5 3
3 2 4
样例输出
3 4
5 2
1 3
评测用例规模与约定
1 ≤ n, m≤ 1,000,矩阵中的数都是不超过1000的非负整数。
思路:存进去,读出来就行,就是一个相对坐标转化。这代码跑的时候,一次过,一次超时的。。。神奇的在线测试。
importjava.util.Scanner;public classCCF201503_1 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int m =sc.nextInt();int n=sc.nextInt();int[][] ret=new int[n][m];for(int j=0;j=0;i--) {
ret[i][j]=sc.nextInt();
}
}for(int i=0;i
System.out.print(ret[i][j]+" ");
}
System.out.print("\n");
}
}
}
试题编号:201503-2
试题名称:数字排序
样例输入
12
5 2 3 3 1 3 4 2 5 2 3 5
样例输出
3 4
2 3
5 3
1 1
4 1
评测用例规模与约定
1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。
思路:简单题,别把自己绕进去就行,就一个排序,排序时注意出现次数一样多,先输出小的。用了冒泡排序。
packageCCF;importjava.util.Arrays;importjava.util.HashSet;importjava.util.Scanner;public classCCF201503_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[] sourse = new int[n];
HashSet hs= newHashSet();for (int i = 0; i < n; i++) {
sourse[i]=sc.nextInt();
hs.add(sourse[i]);
}
Arrays.sort(sourse);int sizes =hs.size();int[][] ret = new int[sizes][2];int flag = 0;for (int i = 0; i < n; i++) {if (i == 0) {
ret[flag][0] =sourse[i];
ret[flag][1]++;continue;
}if (sourse[i] == ret[flag][0]) {//如果和前一个相等
ret[flag][1]++;
}else {//和前一个不相等
flag++;
ret[flag][0] =sourse[i];
ret[flag][1]++;
}
}int temp0 = 0;int temp1 = 0;for (int i = 0; i < sizes; i++) {for (int j = 0; j < sizes - 1 - i; j++) {if (ret[j + 1][1] > ret[j][1]) {
temp0= ret[j + 1][0];
temp1= ret[j + 1][1];
ret[j+ 1][0] = ret[j][0];
ret[j+ 1][1] = ret[j][1];
ret[j][0] =temp0;
ret[j][1] =temp1;continue;
}if (ret[j + 1][1] == ret[j][1]) {if (ret[j + 1][0] < ret[j][0]) {
temp0= ret[j + 1][0];
temp1= ret[j + 1][1];
ret[j+ 1][0] = ret[j][0];
ret[j+ 1][1] = ret[j][1];
ret[j][0] =temp0;
ret[j][1] =temp1;
}
}
}
}for (int i = 0; i < sizes; i++) {
System.out.println(ret[i][0] + " " + ret[i][1]);
}
}
}
试题编号:201509-1
试题名称:数列分段
样例输入
8
8 8 8 0 12 12 8 0
样例输出
5
样例说明
8 8 8是第一段,0是第二段,12 12是第三段,倒数第二个整数8是第四段,最后一个0是第五段。
评测用例规模与约定
1 ≤ n ≤ 1000,0 ≤ ai ≤ 1000。
思路:就是边读边判断是否和前一个一样,如果一样不操作,不一样就加加。
importjava.util.Scanner;public classCCF201509_1 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();if (n == 1) {
System.out.println(1);
}int[] A = new int[n];int ret = 1;for (int i = 0; i < n; i++) {
A[i]=sc.nextInt();if (i != 0) {//除去第一个
if (A[i] != A[i - 1]) {
ret++;
}
}
}
System.out.println(ret);
}
}
试题编号:201509-2
试题名称:日期计算
样例输入
2015
80
样例输出
3
21
样例输入
2000
40
样例输出
2
9
思路:人基本常识必须要有,剩下的就是简答操作了。
importjava.util.Scanner;public classCCF201509_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int year=sc.nextInt();int d=sc.nextInt();int[] mounth=new int[] {31,0,31,30,31,30,31,31,30,31,30,31};if(((year%4==0)&&(year%100!=0))||(year%400==0)) {
mounth[1]=29;
}else{
mounth[1]=28;
}for(int i=0;i<12;i++) {if(d>mounth[i]) {
d-=mounth[i];
}else{
System.out.println(i+1);
System.out.println(d);return;
}
}
}
}
试题编号:201512-1
试题名称:数位之和
样例输入
20151220
样例输出
13
样例说明
20151220的各位数字之和为2+0+1+5+1+2+2+0=13。
评测用例规模与约定
所有评测用例满足:0 ≤ n ≤ 1000000000。
思路:charAt的标准用法之一,注意char转int即可。
importjava.util.Scanner;public classCCF201512_1 {public static voidmain(String[] args) {
Scanner sc=newScanner(System.in);
String sourse=sc.nextLine();int ret=0;for(int i=0;i
ret+=(sourse.charAt(i)-'0');
}
System.out.println(ret);
}
}
试题编号:201512-2
试题名称:消除类游戏
样例输入
4 5
2 2 3 1 2
3 4 5 1 4
2 3 2 1 3
2 2 2 4 4
样例输出
2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4
样例说明
棋盘中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。
样例输入
4 5
2 2 3 1 2
3 1 1 1 1
2 3 2 1 3
2 2 3 3 3
样例输出
2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0
样例说明
棋盘中所有的1以及最后一行的3可以被同时消除,其他的方格中的棋子均保留。
评测用例规模与约定
所有的评测用例满足:1 ≤ n, m ≤ 30。
思路:横向遍历一次,纵向遍历一次,用二维数组对可以消除的置1,并且因为3连可消,下标也直接已知,可以简化一点循环。
importjava.util.Scanner;public classCCF201512_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int m =sc.nextInt();int[][] ret = new int[n][m];int[][] sourse = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {
sourse[i][j]=sc.nextInt();
}
}int[] flag = new int[2];for (int i = 0; i < n; i++) {
flag[0] = sourse[i][0];
flag[1] = 1;for (int j = 1; j < m; j++) {if (flag[0] ==sourse[i][j]) {
flag[1]++;
}else{
flag[0] =sourse[i][j];
flag[1] = 1;
}if (flag[1] >= 3) {
ret[i][j]= 1;
ret[i][j- 1] = 1;
ret[i][j- 2] = 1;
}
}
}for (int j = 0; j < m; j++) {
flag[0] = sourse[0][j];
flag[1] = 1;for (int i = 1; i < n; i++) {if (flag[0] ==sourse[i][j]) {
flag[1]++;
}else{
flag[0] =sourse[i][j];
flag[1] = 1;
}if (flag[1] >= 3) {
ret[i][j]= 1;
ret[i- 1][j] = 1;
ret[i- 2][j] = 1;
}
}
}for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (ret[i][j] == 0) {
System.out.print(sourse[i][j]+ " ");
}else{
System.out.print(0 + " ");
}
}
System.out.println();
}
}
}
试题编号:201604-1
试题名称:折点计数
样例输入
7
5 4 1 2 3 6 4
样例输出
2
评测用例规模与约定
所有评测用例满足:1 ≤ n ≤ 1000,每天的销售量是不超过10000的非负整数。
思路:用flag去记录前一组数据的斜率的正负,如果斜率正负变化,说明发生拐点。
importjava.util.Scanner;public classCCF201604_1 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();if (n == 1) {int mm =sc.nextInt();
System.out.println(0);return;
}if (n == 2) {int mm =sc.nextInt();int mmm =sc.nextInt();
System.out.println(0);return;
}int[] A = new int[n];int flag = 0;int temp = 0;int ret = 0;for (int i = 0; i < n; i++) {
A[i]=sc.nextInt();if (i == 1) {
flag= ZhengOrFu(A[0], A[1]);
}if (i != 0) {
temp= ZhengOrFu(A[i - 1], A[i]);if (temp !=flag) {
ret++;
flag=temp;
}
}
}
System.out.println(ret);
}public static int ZhengOrFu(int m, intn) {if ((n - m) >= 0) {return -1;
}else{return 1;
}
}
}
试题编号:201604-2
试题名称:俄罗斯方块
样例输入
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 0
3
样例输出
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0
思路:这道题我只有90分,因为游戏界面优先,可显示的部分是固定的,所以计算极端情况,额外上下开辟一定空间(4,一个方块的大小),然后计算最多可下落的距离,直接刷新过去就可以了,没有满分可能是没有考虑到一些特殊情况,不过思路可以参考,网上也有很多优秀的简短代码,我的思想比较简单,并且需要改进。
importjava.util.Scanner;public classCCF201604_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int[][] sourse = new int[23][10];for (int i = 4; i < 19; i++) {for (int j = 0; j < 10; j++) {
sourse[i][j]=sc.nextInt();
}
}int[][] block = new int[4][4];for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {
block[i][j]=sc.nextInt();
}
}int startIndex = sc.nextInt() - 1;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (block[i][j] != 0) {
sourse[i][j+ startIndex]++;
}
}
}int[] minBlock = new int[4];int[] minDepth = new int[4];for (int j = 0; j < 4; j++) {for (int i = 3; i >= 0; i--) {if (block[i][j] == 0) {
minBlock[j]++;
}else{break;
}
}
}for (int j = startIndex; j < startIndex + 4; j++) {for (int i = 4; i < 19; i++) {if (sourse[i][j] == 0) {
minDepth[j- startIndex]++;
}else{break;
}
}
}int min = 19;int index = 0;for (int i = 0; i < 4; i++) {if ((minBlock[i] + minDepth[i])
min= minBlock[i] +minDepth[i];
index=i;
}
}for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (block[i][j] == 1) {
sourse[i+ min][j + startIndex]++;
}
}
}
Print(sourse);
}public static void Print(int[][] sourse) {for (int i = 4; i < 19; i++) {for (int j = 0; j < 10; j++) {
System.out.print(sourse[i][j]+ " ");
}
System.out.println();
}
}
}
试题编号:201609-1
试题名称:最大波动
样例输入
6
2 5 5 7 3 5
样例输出
4
样例说明
第四天和第五天之间的波动最大,波动值为|3-7|=4。
评测用例规模与约定
对于所有评测用例,2 ≤ n ≤ 1000。股票每一天的价格为1到10000之间的整数。
思路:边读数据,边计算差值,比较即可。
importjava.util.Scanner;public classCCF201609_1 {public static voidmain(String[] args) {
Scanner sc=newScanner(System.in);int n=sc.nextInt();int[] A=new int[n];int max=0;for(int i=0;i
A[i]=sc.nextInt();if(i!=0) {if(Math.abs((A[i]-A[i-1]))>max) {
max=Math.abs(A[i]-A[i-1]);
}
}
}
System.out.println(max);
}
}
试题编号:201609-2
试题名称:火车购票
样例输入
4
2 5 4 2
样例输出
1 2
6 7 8 9 10
11 12 13 14
3 4
样例说明
1) 购2张票,得到座位1、2。
2) 购5张票,得到座位6至10。
3) 购4张票,得到座位11至14。
4) 购2张票,得到座位3、4。
评测用例规模与约定
对于所有评测用例,1 ≤ n ≤ 100,所有购票数量之和不超过100。
思路:这道题也只拿了90分,思想很简单,就是遍历每一个数组,去匹配剩余的空间,如果够就一口气插入,下标直接更新,数组当前层的大小(length)就是下一次需要插入的坐标,思路很简单,但是只有90分,特殊情况考虑不够,历年的一二题都比较简单,但是需要够细致,考虑完所有的特殊、极限情况。
importjava.util.Scanner;public classCCF201609_2 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[][] space = new int[20][5];int[] sourse = new int[n];for (int i = 0; i < n; i++) {int need =sc.nextInt();
sourse[i]=need;int flag = 0;for (int j = 0; j < 20; j++) {//遍历每一排看空间
if (L(space, j) >=need) {for (int k = 0; k < need; k++) {
space[j][5 - L(space, j)]++;
System.out.print((j* 5 + 5 - L(space, j)) + " ");
}
flag= 1;break;//跳出循环去接收下一个数据
}
}if (flag == 0) {int temp =need;for (int j = 0; j < 20; j++) {if (temp == 0) {break;
}if (L(space, j) > 0) {for (int k = 0; k < need; k++) {
space[j][5 - L(space, j)]++;
System.out.print((j* 5 + k + 1) + " ");
temp--;
}
}
}
}
System.out.println();
}
}public static int L(int[][] space, intindex) {int ret = 0;for (int i = 0; i < 5; i++) {if (space[index][i] == 0) {
ret++;
}
}returnret;
}
}
试题编号:201612-1
试题名称:中间数
样例输入
6
2 6 5 6 3 5
样例输出
5
样例说明
比5小的数有2个,比5大的数也有2个。
样例输入
4
3 4 6 7
样例输出
-1
样例说明
在序列中的4个数都不满足中间数的定义。
样例输入
5
3 4 6 6 7
样例输出
-1
样例说明
在序列中的5个数都不满足中间数的定义。
评测用例规模与约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ ai ≤ 1000。
思路:还是喜欢前几年,用例给两个,并且给的用例面一半会比较广、不同。2种方式,都需要先排序,你要满足大于你的数等于小于你的数,即使是有重复数的情况,这个数也一定在排序后的中间位置上,用这个数去匹配去检验就可以,我的检验不够好,你可以从中间的下标,从中间为原点,左右匹配找到不同的数,然后通过下标计算直接得出大于小于的数的数量。第二种方式就是双向队列,弹头弹尾,注意检验就可以了。
importjava.util.Arrays;importjava.util.Scanner;public classCCF201612_1 {public static voidmain(String[] args) {
Scanner sc= newScanner(System.in);int n =sc.nextInt();int[] sourse = new int[n];for (int i = 0; i < n; i++) {
sourse[i]=sc.nextInt();
}
Arrays.sort(sourse);if (n % 2 == 0) {int a = sourse[n / 2 - 1];int b = sourse[n / 2];if (a ==b) {int count = 0;for (int i = 0; i < n; i++) {if (sourse[i]
count++;
}if (sourse[i] >a) {
count--;
}
}if (count == 0) {
System.out.println(a);
}else{
System.out.println(-1);
}
}else{int countA = 0;int countB = 0;for (int i = 0; i < n; i++) {if (sourse[i]