ccf俄罗斯方块解题文档

折点计数完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.Scanner;
public class Main
{
public static void main (String [] args)
{
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
//用数组来存储每一天的销量
int [] rag = new int [n];
for (int i = 0; i < n; i++)
{
rag[i] = scan.nextInt();
}
//标记折点的个数
int count = 0;
for (int i = 1; i < n-1; i++)
{
//如果刚开始是递增
if (rag[i-1] < rag[i])
{
//寻找折点
if (rag[i] > rag[i+1])
{
count++;
}
}
//如果刚开始递减
else
{
//寻找折点
if (rag[i] < rag[i+1])
{
count++;
}
}
}
System.out.println(count);
}
}

俄罗斯方块程

思路

1.将44矩阵中的方块抠出来,用两个数组x[]和y[]来表示其中的位置。
2.将x[]和y[]置于15
10的矩阵中,不断的下沉,碰到1就停止,位置就为当前y轴减去1。
3.如果一直有一个方块,碰到最底下(15*10的边界),将整个循环结束。

outer的用法

·outer就是一个标签,java中的标签就是一个紧跟着英文冒号(:)的标识符。与其他语言不同的是,java中的标签只有放在循环语言之前才有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Condition {
public static void main(String[] args) {
// 外层循环,outer作为标识符
outer: for (int i = 0; i < 5; i++) {
// 内层循环
for (int j = 0; j < 3; j++) {
System.out.println("i的值为:"+i+"j的值为:" + j);
if (j == 1) {
// 跳出outer标签所标识的循环
break outer;
}
}
}
}
}

当程序从外层循环进入内层循环后,当j等于1时,程序遇到一个break outer;语句,这行代码将会导致结束outer标签指定的外层循环,而不是结束break所在的循环,outer可以用其它的词来代替。

示例

示例输入
//方阵
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 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
//组合体下落到倒数第二行第四列开始部分

核心分析

整个程序的难点就是下移和判断

首先获取这个方块每个节点在4*4矩阵中的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
int[] x = new int[4];
int[] y = new int[4];
int z = 0;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(arrSqu[i][j]==1){
x[z]=i;
y[z]=j+column-1;
z++;
}
}
}
```
4*4组合体矩阵中组合体所处位置(1,1),(1,2),(1,3),(2,3)
去掉全0行后组合体各小块的位置
x[0]=1,y[0]=3;
x[1]=1,y[1]=4;
x[2]=1,y[2]=5;
x[3]=2,y[3]=5;
可见这里的位置中,x对应的是除去全0的行以后的行数,y是进入方阵以后对应的列的位置
然后是判断下移
```JAVA
boolean flag = true;
int count=0;
int offset =0;
outer:
while(flag){
for(int i=0;i<4;i++){
//判断最下面的边界,如果有一个方块到了最下面,直接结束下沉,
if((x[i]+offset)==14){
for(int j=0;j<4;j++){
arr[x[j]+offset][y[j]]=1;
}
break outer;
}
if(arr[x[i]+offset][y[i]]==0){//不断的下沉
count++;
}
}
```
此处判断完四个方块以后,也就是count=4时,说明此时该组合体处于一个还可以下移的位置,于是进行下一步,将下降层offset自增,同时将count重新赋值为0,进行下层情况判断
```JAVA
if(count==4){
offset++;
count=0;
}
```
当count不足4时,说明组合体已经压线,则退一层即为落脚点
```JAVA
else{
for(int i=0;i<4;i++){
arr[x[i]+offset-1][y[i]]=1;
}
flag = false;
}
}

完整程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Main.run();
}
public static void run(){
Scanner sc = new Scanner(System.in);
int[][] arr = new int[15][10];
int[][] arrSqu = new int[4][4];
//将输入的方格图存入数组
for(int i=0;i<15;i++){
for(int j=0;j<10;j++){
arr[i][j] = sc.nextInt();
}
}
//将方块存入数组
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
arrSqu[i][j] = sc.nextInt();
}
}
//获取方块将要下沉的位置,偏移
int column = sc.nextInt();
//首先获取这个方块每个节点在4*4矩阵中的位置
int[] x = new int[4];
int[] y = new int[4];
int z = 0;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(arrSqu[i][j]==1){
x[z]=i;
y[z]=j+column-1;
z++;
}
}
}
boolean flag = true;
int count=0;
int offset =0;
outer:
while(flag){
for(int i=0;i<4;i++){
//判断最下面的边界,如果有一个方块到了最下面,直接结束下沉,
if((x[i]+offset)==14){
for(int j=0;j<4;j++){
arr[x[j]+offset][y[j]]=1;
}
break outer;
}
if(arr[x[i]+offset][y[i]]==0){//不断的下沉
count++;
}
}
if(count==4){
offset++;
count=0;
}else{
for(int i=0;i<4;i++){
arr[x[i]+offset-1][y[i]]=1;
}
flag = false;
}
}
//遍历下沉后的矩阵
for(int i=0;i<15;i++){
for(int j=0;j<10;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}