信号发射和接收
知识点数组栈 单调栈时间限制: 1s 空间限制: 256MB 限定语言:不限
题目描述:
有一个二维的天线矩阵,每根天线可以向其他天线发射信号也能接收其他天线的信号,为了简化起见,我们约定每根天线只能向东和向南发射信号,换言之,每根天线只能接收东向或南向发送的信号。
每根天线有自己的高度anth,各根天线的高度存储在一个二维数组中,各个天线的位置用[r, c]表示,r代表天线的行位置 (从0开始编号),c代表天线的列位置 (从0开始编号)
在某一方向 (东向或南向),某根天线可以收到多根其他天线的信号 (也可能收不到任何其他天线的信号),对任一天线X和天线Y,天线X能接收到天线Y的信号的条件是:
天线X在天线Y的东边或南边;
天线X和天线Y之间的其他天线的高度都低于天线X和天线Y,或天线X和天线Y之间无其他天线,即无遮挡,
如下图1示意:
在天线矩阵的第0行上,天线[0,0]接收不到任何其他天线的信号天线[0,1]可以接收到天线[0.0]的信号,天线[0,2]可以接收到天线[0,1]的信号天线[0,3]可以接收到天线[0,1]和天线[0,2]的信号,天线[0,4]可以接收到天线[0,3]的信号,天线[0,5]可以接收到天线[0,4]的信号;在天线矩阵的第0列上,天线[0,0]接收不到任何其他天线的信号,天线[1,0]可以接收到天线[0,0]的信号,天线[2,0]可以接收到天线[1,0]的信号,天线[3,0]可以接收到天线[1.0]和天线[2.0]的信号,天线[4,0]可以接收到天线[3,0]的信号,天线[5,0]可以接收到天线[3,0]和天线[4,0]的信号
给一个m行n列的矩阵(二维数组),知阵存储各根天线的高度,求出每根天线可以收到多少根其他天线的信号,结果输出到m行n列的矩阵(维数组) 中。
输入描述:
输入为1个m行n列的矩阵 (二维数组) anthh[m][n],矩阵存储各根天线的高度,高度值anthh[n[c]为大于0的整数。具体示例如下:
m n
anth[0][0] anth[0][1] ... anth[0][n-1] anth[1][0] anth[1][1] ... anth[1][n-1] ... anth[m-1][0]anth[m-1][n-1]
第1行为输入矩阵的行数和列数
第2行为输入矩阵的元素值,按行输入
输出描述:
输出1个m行n列的矩阵 (二维数组) ret[m][n],矩阵存储每根天线能收到多少根其他天线的信号,根数为ret][c]。具体示例如下:
m n
ret[0][0] ret[0][1] ... ret[0][n-1] ret[1][0] ret[1][1] ... ret[1][n-1] ... ret[m-1][0] ... ret[m-1][n-1]
第1行为输出矩阵的行数和列数
第2行为输出矩阵的元素值,按行输出
补充说明:
1 <= m <= 500
1<= n <= 500
0 < ant[r][c] <10^5
示例1
输入:
1 6
2 4 1 5 3 3
输出:
1 6
0 1 1 2 1 1
说明:
输入为1行6列的天线矩阵的高度值
[2 4 1 5 3 3]
输出为1行6列的结果矩降
[0 1 1 2 1 1]
示例2
输入:
2 6
2 5 4 3 2 8 9 7 5 10 10 3
输出:
2 6
0 1 1 1 1 4 1 2 2 4 2 2
说明:
输入为2行6列的天线知阵高度值
[2 5 4 3 2 8]
[9 7 5 10 10 3]
输出为2行6列的结果矩阵
[0 1 1 1 1 4]
[1 2 2 4 2 2]
结果说明:
天线[0,0]收不到任何其他天线的信号,因此ret[0,0]=0;
天线[0,1]可接收到天线[0,0]的信号,因此ret[0,1]=1;
天线[0,2]可以接收到天线[0,1]的信号,因此retf0,2]=1;
天线[0,3]可以接收到天线[0,2]的信号,因此ret[0,3]=1;
天线[0,4]可以接收到天线[0.3]的信号,因此ret[0,4]=1;
天线[0,5]可以接收到天线[0,1]、天线[0,2]、天线[0,3]、天线[0,4]的信号,因此ret[0,5]=4
天线[1,0]可以接收到天线[0,0]的信号,因此ret[1,0]=1;
天线[1,1]可以接收到天线[0,1]、天线[1,0]的信号,因此ret[1,1]=2;
天线[1,2]可以接收到天线[0,2]、天线[1,1]的信号,因此ret[1,2]=2;
天线[1,3]可以接收到天线[0,3]、天线[1,0]、天线[1,1]、天线[1,2]的信号,因此ret[1,3]=4;
天线[1,4]可以接收到天线[0,4]、天线[1,3]的信号,因此ret[1,4]=2;
天线[1,5]可以接收到天线[0,5]、天线[1,4]的信号,因此ret[1,5]=2
解题思路:
求天线接收信号的个数,如图:
如求[0,5]可接收的信号:
以左侧第一根天线为最大值max=[0,4]=2,可以接收到信号,count=1;
[0,3]=1<max,接收不到此天线的信号,count=1;
[0,2]=3==[0,5]>max,可以接收到信号,count=2,且max =3;
因为与接收天线等高,所以往后的天线都没有办法接收到信号了。所以count=2。
java代码:
代码解读:
这段代码是一个天线接收信号的问题。代码首先通过Scanner类从标准输入中读取行数和列数,然后初始化一个二维数组来存储输入的天线高度。接下来,代码循环计算每个天线的接收信号数,通过调用rowSignal和colSignal方法来计算行信号接收数和列信号接收数之和。最后,代码输出行数和列数,以及计算出的结果字符串。
rowSignal方法用于计算当前天线的行信号接收数。首先,代码判断当前天线是否在第一列,如果是,则没有行信号接收。然后,代码以当前天线左侧的第一根天线作为最大值,从当前天线左侧第二根天线开始往左遍历。如果最大高度大于等于接收天线,则后面的天线发射的信号都无法接收。如果当前天线的高度大于最大高度,则表示可以接收到信号,接收信号数加1,同时更新最大高度。最后,代码返回行信号接收数。
colSignal方法用于计算当前天线的列信号接收数。首先,代码判断当前天线是否在第一行,如果是,则没有列信号接收。然后,代码以当前天线上面的第一根天线为最大值,从当前天线上方第二根天线开始往上遍历。如果最大高度大于等于接收天线,则后面的天线发射的信号都无法接收。如果当前天线的高度大于最大高度,则表示可以接收到信号,接收信号数加1,同时更新最大高度。最后,代码返回列信号接收数。
import java.util.Scanner;
public class Main{
public static int[][] ints; //定义一个二维数组,用于存储输入的天线高度
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int r = sc.nextInt(); //输入行数
int c = sc.nextInt(); //输入列数
ints = new int[r][c]; //初始化数组
for(int i=0;i<r;i++){ //循环输入每个天线的高度
for(int j=0;j<c;j++){
ints[i][j] = sc.nextInt();
}
}
String res = ""; //定义一个字符串,用于存储结果
for(int i=0;i<r;i++){ //循环计算每个天线的接收信号数
for(int j=0;j<c;j++){
int count = rowSignal(i,j) + colSignal(i,j); //计算行信号接收数和列信号接收数之和
res += count + " "; //将结果添加到字符串中
}
}
System.out.println(r + " " + c); //输出行数和列数
System.out.println(res.substring(0,res.length()-1)); //输出结果字符串,去掉最后一个空格
}
/**
* 求行接收信号数
* @param row 当前天线所在的行数
* @param col 当前天线所在的列数
* @return 返回当前天线的行信号接收数
*/
public static int rowSignal(int row, int col){
if(col==0){ //在第 1 列没有行信号接收
return 0;
}
int max = ints[row][col-1]; //以此天线左侧的第一根天线作为最大值
int count = 1; //左侧第一根一定能接收到信号,所以至少有 1 个
for(int i=col-2; i>=0; i--){ //从当前天线左侧第二根天线开始往左遍历
if(max >= ints[row][col]){ //当最大高度大于等于接收天线时,后面的天线发射的信号都无法接收
break;
}
int height = ints[row][i]; //获取当前天线的高度
if(height>max){ //此地的天线是当前最高天线时,表示可以接收到信号
count++; //接收信号数加 1
max = height; //更新最大高度
}
}
return count; //返回行信号接收数
}
/**
* 求列信号接收数
* @param row 当前天线所在的行数
* @param col 当前天线所在的列数
* @return 返回当前天线的列信号接收数
*/
public static int colSignal(int row, int col){
if(row==0){ //在第 1 行没有列信号接收
return 0;
}
int max = ints[row-1][col]; //以此天线上面的第一根天线为最大值
int count = 1; //上侧第一根一定能接收到信号,所以至少有 1 个
for(int i=row-2; i>=0; i--){ //从当前天线上方第二根天线开始往上遍历
if(max >= ints[row][col]){ //当最大高度大于等于接收天线时,后面的天线发射的信号都无法接收
break;
}
int height = ints[i][col]; //获取当前天线的高度
if(height>max){ //此地的天线是当前最高天线时,表示可以接收到信号
count++; //接收信号数加 1
max = height; //更新最大高度
}
}
return count; //返回列信号接收数
}
}
C++代码:
#include <iostream>
using namespace std;
// 计算当前位置在行方向上的信号强度
int rowSignal(int row, int col, int** ints) {
if(col == 0) { // 如果当前位置在第一列,则无法向左计算信号强度
return 0;
}
int max = ints[row][col-1]; // 初始化最大高度为当前位置左侧的高度
int count = 1; // 初始化信号强度为1
for(int i=col-2; i>=0; i--) { // 从当前位置左侧第二个位置开始向左遍历
if(max >= ints[row][col]) { // 如果当前位置的高度小于等于左侧位置的高度,则无法向左传递信号
break;
}
int height = ints[row][i]; // 获取当前位置左侧的高度
if(height > max) { // 如果当前位置左侧的高度大于最大高度,则信号强度加1,并更新最大高度
count++;
max = height;
}
}
return count; // 返回信号强度
}
// 计算当前位置在列方向上的信号强度
int colSignal(int row, int col, int** ints) {
if(row == 0) { // 如果当前位置在第一行,则无法向上计算信号强度
return 0;
}
int max = ints[row-1][col]; // 初始化最大高度为当前位置上方的高度
int count = 1; // 初始化信号强度为1
for(int i=row-2; i>=0; i--) { // 从当前位置上方第二个位置开始向上遍历
if(max >= ints[row][col]) { // 如果当前位置的高度小于等于上方位置的高度,则无法向上传递信号
break;
}
int height = ints[i][col]; // 获取当前位置上方的高度
if(height > max) { // 如果当前位置上方的高度大于最大高度,则信号强度加1,并更新最大高度
count++;
max = height;
}
}
return count; // 返回信号强度
}
int main() {
int r, c;
cin >> r >> c; // 输入矩阵的行数和列数
int** ints = new int*[r]; // 动态分配二维数组的内存空间
for(int i=0; i<r; i++) {
ints[i] = new int[c];
}
for(int i=0; i<r; i++) { // 输入矩阵的每个元素
for(int j=0; j<c; j++) {
cin >> ints[i][j];
}
}
string res = ""; // 初始化结果字符串
for(int i=0; i<r; i++) { // 遍历矩阵的每个位置
for(int j=0; j<c; j++) {
int count = rowSignal(i, j, ints) + colSignal(i, j, ints); // 计算当前位置的信号强度
res.append(to_string(count) + " "); // 将信号强度添加到结果字符串中
}
}
cout << r << " " << c << endl; // 输出矩阵的行数和列数
cout << res.substr(0, res.length()-1) << endl; // 输出结果字符串,去掉最后一个空格
return 0;
}
python代码:
def rowSignal(row, col, ints):
# 计算行信号
if col == 0:
return 0
# 如果列数为0,返回0
max_height = ints[row][col-1]
# 初始化最大高度为当前位置左侧的高度
count = 1
# 初始化信号数量为1
for i in range(col-2, -1, -1):
# 从当前位置左侧第二个位置开始向左遍历
if max_height >= ints[row][col]:
# 如果当前位置左侧的高度大于等于当前位置的高度,跳出循环
break
height = ints[row][i]
# 获取当前位置左侧的高度
if height > max_height:
# 如果当前位置左侧的高度大于最大高度,信号数量加1,最大高度更新为当前位置左侧的高度
count += 1
max_height = height
return count
def colSignal(row, col, ints):
# 计算列信号
if row == 0:
return 0
# 如果行数为0,返回0
max_height = ints[row-1][col]
# 初始化最大高度为当前位置上方的高度
count = 1
# 初始化信号数量为1
for i in range(row-2, -1, -1):
# 从当前位置上方第二个位置开始向上遍历
if max_height >= ints[row][col]:
# 如果当前位置上方的高度大于等于当前位置的高度,跳出循环
break
height = ints[i][col]
# 获取当前位置上方的高度
if height > max_height:
# 如果当前位置上方的高度大于最大高度,信号数量加1,最大高度更新为当前位置上方的高度
count += 1
max_height = height
return count
# 主函数
if __name__ == '__main__':
r, c = map(int, input().split())
# 获取矩阵的行数和列数
ints = []
tmp_list = list(map(int, input().split()))
# 获取矩阵中每个位置的高度
for i in range(r):
tmp = []
for j in range(c):
tmp.append(tmp_list[c * i + j])
ints.append(tmp)
res = ""
# 初始化结果字符串
for i in range(r):
for j in range(c):
count = rowSignal(i, j, ints) + colSignal(i, j, ints)
# 计算当前位置的行信号和列信号之和
res += str(count) + " "
# 将结果添加到结果字符串中
print(r, c)
# 输出矩阵的行数和列数
print(res[:-1])
# 输出结果字符串,去掉最后一个空格
做题心得:
这段python代码又使用到了这段代码,和【华为OD机试真题】计算网络信号中的用法类似,请同学们务必掌握。
tmp_list = list(map(int, input().split()))
# 获取矩阵中每个位置的高度
for i in range(r):
tmp = []
for j in range(c):
tmp.append(tmp_list[c * i + j])
ints.append(tmp)