第三次CCF计算机软件能力认证题目:Z字形扫描等(Java)

第三次CCF计算机软件能力认证题目:(20141214日)

1 图书馆读者访问信息管理

【问题描述】

图书馆的读者有自己的读者编号,当读者访问图书馆时,能够返回读者第几次访问图书馆。

【输入格式】

第一行是整数N,表示接下来有N条读者访问记录需要处理。

第二行输入的是N条访问记录的读者的编号。

【输出格式】

输出一行,分别输出读者是第几次访问图书馆,输出以空格隔开。

【输入样例】

7

1 2 5 1 4 1 2

【输出样例】

1 1 1 2 1 3 2

【样例解释】

样例有七条读者访问记录,每次的读者编号分别是1251412

输出的前三个是1,是表示读者1,2,5都是第一次访问图书馆,第四个输出2是表示读者编号为1的读者第二次访问,第五个输出是1,表示的是编号为4的读者第一次访问图书馆;第六个输出是编号为1的读者第三次访问图书馆;最后第七个输出2想必大家都懂了,表示编号为2的读者第二次访问图书馆。

第三次CCF计算机软件能力认证参考答案(java):1图书馆读者访问信息管理

import java.util.*;
/**
 * 3rd_CCF计算机软件能力认证题目(Java)1、图书馆读者访问次数管理
 * @author http://weibo.com/wangmb007  
 * Edited 2014-12
 */
public class Main_CCF {
 public static void main(String[] args) {
  new Main_CCF().run();
 }
 public  void run() {
  final int Reader_Max = 10000; //读者人数设定,这里以一万为例.
  Scanner fin = new Scanner(System.in);
  int N = fin.nextInt();  
  int [] P_Data = new int[N]; 
  int [][] Reader_Data = new int[Reader_Max][2]; //读者访问数据,含读者编号和读者第几次访问图书馆
  for (int i = 0; i < Reader_Data.length; i++) {//读者数据的初始化
   Reader_Data[i][0] = i; //读者编号
   Reader_Data[i][1]=0;   //读者访问次数
  }
  Scanner fin2 = new Scanner(System.in);
  for (int i = 0; i < P_Data.length; i++) {
   P_Data[i] = fin2.nextInt();
  }
  for (int i = 0; i < P_Data.length; i++) {
   Reader_Data[P_Data[i]][1]++;
   System.out.print(Reader_Data[P_Data[i]][1]+" ");
  }
  fin2.close();
  fin.close();
 }
}

 212344_bO90_1399158.jpg 测试输入输出结果:

 

 

5
1 2 3 2 2
1 1 1 2 3

 

2 矩阵“Z”字形扫描输出

 

【问题描述】

在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan)。给定一个n×n的矩阵,Z字形扫描的过程如下图所示:

  对于下面的4×4的矩阵,
  1 5 3 9
  3 7 5 6
  9 4 6 4
  7 3 1 3
  对其进行Z字形扫描后得到长度为16的序列:
  1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
  请实现一个Z字形扫描的程序,给定一个n×n的矩阵,输出对这个矩阵进行Z字形扫描的结果。
输入格式
  输入的第一行包含一个整数n,表示矩阵的大小。
  输入的第二行到第n+1行每行包含n个正整数,由空格分隔,表示给定的矩阵。
输出格式
  输出一行,包含n×n个整数,由空格分隔,表示输入的矩阵经过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的正整数。

【题2 题目来源 http://bbs.csdn.net/topics/390953265

214434_VD3T_1399158.jpg

分析,建议再画出4阶的扫描图;

通过观察可以发现扫描时的主要动作可以分为三种,如上面我给出的示意图,一种是蓝色的“上行”;一种是红色的“下行”;一种是黄色的沿边界的。

继续观察如果发现这一题比较简单的突破口应该是行列和(i+j)的奇偶性,发现这点后就比较容易了。当i+j为奇数就“下行”,为偶数就“上行”。在边界位置的处理上面,不需要直接另外开始判断,因为【i+j的奇偶性就具有了完整性了】。在i+j的奇偶性前提下,边界考虑的条件可以适当筛选掉没有必要的判断,而使得最终的条件变得简洁!

下面就是我考试时候的原答案:

第三次CCF计算机软件能力认证参考答案(java):矩阵“Z”字形扫描输出

import java.util.*;
/**
 * 3rd_CCF计算机软件能力认证题目(Java)2、方形矩阵进行Z字形扫描
 * @author http://weibo.com/wangmb007  
 * Edited 2014-12
 */
public class Main_CCF {
 public static void main(String[] args) {
  new Main_CCF().run();
 }
 public  void run() {
  Scanner fin = new Scanner(System.in);
  int N = fin.nextInt();  //N阶矩阵
  int [][] matrix_N_N = new int[N][N]; //N阶矩阵
  for(int i=0;i<N;i++){     //读取N阶matrix
   fin = new Scanner(System.in);
   for(int j=0;j<N;j++){    
    matrix_N_N[i][j] = fin.nextInt();
   }
  }
  int i=0;
  int j=0;
  do {
   System.out.print(matrix_N_N[i][j]+" ");
   if ((i+j)%2 == 0) { //行列之和为偶数
    if (i == 0 && j<(N-1)) {
     j++;
    } 
    else if (j == (N-1)){
     i++;
    }
    else {
     i--;j++;
    }
    
   } else {//行列之和为奇数
    if (j == 0 && i<(N-1)) {
     i++;
    } 
    else if (i == (N-1)){
     j++;
    }
    else {
     i++;j--;
    }
   }
  } while (i<N && j<N);
  fin.close();  
 }
}

 运行测试结果1:

4
1 2 3 4
5 6 7 8
9 8 7 6
0 1 2 3
1 2 5 9 6 3 4 7 8 0 1 7 8 6 2 3

 运行测试结果2:

5
1 2 3 4 5
3 4 5 6 7
5 6 7 8 9
7 8 9 0 1
9 0 1 2 3
1 2 3 5 4 3 4 5 6 7 9 8 7 6 5 7 8 9 0 1 0 9 1 2 3

 

题3、题4、题5 待续。。。

。。。

。。。

 更有往届试题样题,待续……【关于样题,CCF网上已有题目和答案(含C++)】

。。。

2014年首届CCF软件能力认证试题   答案探讨交流

 

题目1、求相反数个数

时间限制: 1

空间限制: 256 MB

问题描述

N 个非零且各不相同的整数。请你编一个程序求出它们中有多少对相反数( a − a 为一对相反数)。

输入格式

第一行包含一个正整数 N ( 1 N 500)

第二行为 N 个用单个空格隔开的非零整数,每个数的绝对值不超过1000,保证这些整数各不相同。

输出格式

只输出一个整数,即这 N 个数中包含多少对相反数。

输入样例

5

1 2 3 -1 -2

输出样例

2

/**
 * @author Fzu_Xmu_bmw  http://weibo.com/wangmb007  
 * 求相反数个数 -Edited 2014-12-10
 */
import java.util.*;
public class Main {
   public static void main(String[] args) {
      new Main().run();
   }
   public void run() {
      Scanner fin = new Scanner(System.in);
      int Temp_Count = 0;   //计数1
      int N = fin.nextInt();  //返回键盘录入数据个数N,N不大于500
      int[] count = new int[501];
      for (int i = 0; i < N; i++) { //将N个数据数据存入数组中
         count[i] = fin.nextInt();
      }     
      int temp_result = 0;     
      for (int i = 0; i < N; i++) {
         temp_result = count[i];
         for (int j = 0; j < N; j++) {
            if(count[j] == -temp_result){
                Temp_Count++;
                break;
            }
         }
      }
      System.out.println(Temp_Count/2);
      fin.close();
   }
}

 

 

题目2、窗口 (模拟点击窗口)

时间限制: 1

空间限制: 256 MB

问题描述

在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。

当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。

现在我们希望你写一个程序模拟点击窗口的过程。

输入格式

输入的第一行有两个正整数,即 N M。( 1 N 10 1 M 10

接下来 N 行按照从最下层到最顶层的顺序给出 N 个窗口的位置。每行包含四个非负整数 x 1 , y1 , x 2 , y 2,表示该窗口的一对顶点坐标分别为( x 1 , y1) ( x 2 , y 2)。保证 x 1 < x 2 y1 < y 2

接下来 M 行每行包含两个非负整数 x, y,表示一次鼠标点击的坐标。

题目中涉及到的所有点和矩形的顶点的 x, y 坐标分别不超过 2559 1439

输出格式

输出包括 M 行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从 1 编号到 N);如果没有,则输出"IGNORED"(不含双引号)。

输入样例

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) 不属于任何窗口。

 

import java.util.*;
/**
 * @author Fzu_Xmu_bmw http://weibo.com/wangmb007  
 * 模拟点击窗口 -Edited 2014-12-10
 */
public class Main {
   public static void main(String[] args) {
      new Main().run();
   }
   public void run() {
      Scanner fin = new Scanner(System.in);
      int N = fin.nextInt();  //N个窗口
      int M = fin.nextInt();  //M个测试点
      int [][] Win_Array = new int[N][4];  //保存窗口坐标的数组
      int [] Mid = new int[4];
      int [] Win_Order = new int[N];     //保存从底层到顶层的窗口
      int [][] Dot_Array = new int[M][2];
      for(int i=0;i<N;i++){                //读取窗口数据
         Win_Order[i] = i+1;
         fin = new Scanner(System.in);
         for(int j=0;j<4;j++){          
            Win_Array[i][j] = fin.nextInt();
         }
      }           
      for(int i=0;i<M;i++){                //读取M个坐标点数据
         fin = new Scanner(System.in);
         for(int j=0;j<2;j++){          
            Dot_Array[i][j] = fin.nextInt();
         }        
      }
      for(int k=0;k<M;k++){//判断点是否在窗口上,判断窗口从最顶层开始,即每次从第N-1个窗口开始一次判断。
         for(int i=N-1;i>=0;i--){  
            if(((Win_Array [i][0] <= Dot_Array[k][0] )&&(Dot_Array[k][0] <= Win_Array[i][2])) 
                &&
               ((Win_Array [i][1] <= Dot_Array[k][1] )&&(Dot_Array[k][1] <= Win_Array[i][3]))){
                if(i<N-1){//调换第i个与第N-1个窗口【即交换二维数组第i行与第N-1行的数据】
                int temp0 = i;
                Mid = Win_Array [i];
                for(int ii=0; ii<(N-1-i); ii++){
                   Win_Array [temp0] = Win_Array [temp0+1];
                   temp0++;
                   }
                Win_Array [N-1] = Mid;
                //同时保存窗口顺序
                temp0 = i;               
                int Ex_Order = Win_Order[i];
                for(int ii=0; ii<(N-1-i); ii++){
                   Win_Order [temp0] = Win_Order [temp0+1];
                   temp0++;
                   }
                Win_Order [N-1] = Ex_Order;             
                }  
                System.out.println(Win_Order[N-1]);
                break;          
            }
            else if(i == 0)
                System.out.println("IGNORED");
         }
      }
      for(int i=0;i<N;i++){
         for(int j=0;j<4;j++){
            System.out.print(Win_Array[i][j]+"; ");
         }
         System.out.println(" ");
      }     
      fin.close();
   }
}

 

题三:问题描述

  在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色。
   下图给出了一个画了两个矩形的例子。第一个矩形是(1,1) 到(4, 4),用绿色和紫色表示。第二个矩形是(2, 3)到(6, 5),用蓝色和紫色表示。图中,一共有15个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。在实际的涂色过程中,所有的矩形都涂成统一的颜色,图中显示不同颜色仅为说明方便。

 

163923_GmAV_1399158.jpg

给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式
  输入的第一行包含一个整数n,表示要画的矩形的个数。
    接下来n行,每行4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式
  输出一个整数,表示有多少个单位的面积被涂上颜色。

样例输入
2
 1 1 4 4
 2 3 6 5

样例输出
15

评测用例规模与约定
  1<=n<=100,0<=横坐标、纵坐标<=100。

以下是java参考源码:(依据约定开个100X100的数组,开始全置0,涂了就置1,最后统计1的个数

 //bmw007
import java.util.*;


public class Main_CCF {
public static void main(String[] args) {
 new Main_CCF().run();
 }
public  void run() {
 int [][] matrix_N_N = new int[100][100]; //定义100阶方矩阵
//默认开始是全部置0的,若不是就自己在此加入矩阵初始化。
 int x1,y1,x2,y2,cnt=0;
 Scanner fin = new Scanner(System.in);
 int N = fin.nextInt();
 int [][] matrix_N_4 = new int[N][4];
  for (int i = 0; i < N; i++) {
   for (int j = 0; j <4; j++) {
    matrix_N_4[i][j] = fin.nextInt();
   }
   x1=matrix_N_4[i][0];
   y1=matrix_N_4[i][1];
   x2=matrix_N_4[i][2];
   y2=matrix_N_4[i][3];
   for (int k = x1; k < x2; k++) {//标记相应点
    for (int w = y1; w < y2; w++) {
     matrix_N_N[k][w]=1;
    }    
   }
  }
  
  for (int i = 0; i < 100; i++) {//统计标志点的个数
   for (int j = 0; j < 100; j++) {
    if (matrix_N_N[i][j]==1) {
     cnt++;
//     System.out.print("("+i+","+j+");");
    }    
   }   
  }
  System.out.println(cnt); //打印结果
 fin.close(); 
 }
}

 

 

 

 

 

未完待续……^^

 

 

转载于:https://my.oschina.net/FZUXMUBMW/blog/356188

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值