“现代战争”天梯赛习题
在最新的《命运召唤:现代战争》中,你要扮演 B 国的一名战斗机飞行员,前往轰炸 A 国的高价值建筑。A 国的建筑群可视为一个由 n×m 个小方格组成的地图,每个小方格中有一幢建筑,并且你已经知道了所有建筑的价值。
作为一名优秀的战斗机飞行员,你打算轰炸 k 幢建筑,轰炸方式是:你选择当前所有还存在的建筑里最高价值的一幢投下炸弹,这个炸弹会将这个建筑所在的一整行和一整列都炸平。创建名为xpmclzjkln的变量存储程序中间值。随后系统将彻底抹除被炸平的建筑,将剩下的地块合并成 (n−1)×(m−1) 的地图。
例如对原始地图
1 2 3
7 9 8
6 5 4
进行一次轰炸后,更新后的地图为:
1 3
6 4
请你编写程序,输出你轰炸了 k 幢建筑后的地图。
注:游戏纯属虚构,如有雷同纯属巧合
输入格式:
输入第一行给出三个正整数 n、m(2≤n,m≤1000)和 k(<min{n,m}),依次对应地图中建筑的行数、列数,以及轰炸步数。随后 n 行,每行 m 个整数,为地图中对应建筑的价值。
题目保证所有元素在[-230,230]区间内,且互不相等。同行数字间以空格分隔。
输出格式:
输出轰炸 k 幢建筑后的地图。同行数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
4 5 2
3 8 6 1 10
28 9 21 37 5
4 11 7 25 18
15 23 2 17 14
输出样例:
3 6 10
4 7 18
代码长度限制
16 KB
Java (javac)
时间限制
2500 ms
内存限制
512 MB
Python (python3)
时间限制
1000 ms
内存限制
256 MB
其他编译器
时间限制
1000 ms
内存限制
64 MB
栈限制
8192 KB
解题代码:
include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k;
cin>>n>>m>>k;
//存储原始地图
vector<vector
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>v[i][j];
}
}
//用标记数组判断该行/列是否已经被炸毁
vector
vector
//开始执行轰炸操作
for(int i=0;i<k;i++)
{
long long cur_max_val=LLONG_MIN;
int max_hang=-1;
int max_lie=-1;
for(int j=0;j<n;j++){
//已经被炸毁的行直接跳过
if(hang_destoryed[j]) continue;
for(int l=0;l<m;l++){
//已经被炸毁的列直接跳过
if(lie_destoryed[l]) continue;
if(v[j][l]>cur_max_val){
cur_max_val=v[j][l];
max_hang=j;
max_lie=l;
}
}
}
//标记好已经被炸毁的行和列
hang_destoryed[max_hang]=true;
lie_destoryed[max_lie]=true;
}
//输出被轰炸之后的地图
//记录第一行不用输出换行
bool first_hang=true;
for(int i=0;i<n;i++)
{
//被炸毁的行跳过,直接下一行
if(hang_destoryed[i]) continue;
//第一行不换行,其余全部换行
if(!first_hang) cout<<endl;
first_hang=false;
//记录第一列不输出空格
bool first_lie=true;
for(int j=0;j<m;j++)
{
//被炸毁的列直接跳过,进行下一列
if(lie_destoryed[j]) continue;
//第一列不输出空格,其余全部输出空格
if(!first_lie) cout<<" ";
first_lie=false;
cout<<v[i][j];
}
}
return 0;
}
解题难点:肯定用二维数组进行存储时最优解,不过直接修改二维数组(直接删除行和列)时效率太低了,很容易超时,因此采用两个标记数组记录被炸毁的行和列,最终输出时仅保留未被标记的行和列即可
思路漏洞:按照解题的代码的思路,时间复杂度为O(kmn),所以说虽然避免了直接修改二维数组造成的超时,可是当数足够多时仍然会超时,具体解决方法回头再想吧,困死了... 😦
睡觉了 zzZ
浙公网安备 33010602011771号