先看题目:
输入输出格式与数据范围:
可能这道题目有点绕,先给读者解读下题意:
以测试样例为例,就是首先n,m分别代表了楼层数和每一层楼的房间数目,然后样例n,m分别不是2、3嘛,然后接下来输入的每三行就代表了一层楼的每个房间,每一行两个数字,第一个数字为0 1表示该房间是否存在楼梯通往下一层楼,第二个数字就是代表了房间里面指示牌的数字。
然后最下面那一行一个数字代表了一开始从最底层的哪一个房间号开始探险。
接下来我阐述一下我的个人思路:
首先利用两个二维数组,第一个二维数组stair表示每一层的每个房间是否有能通往上一层的楼梯,第二个二维数组代表每一层的每个房间指示牌上面的数字,话不多说,先上我一开始不能得到满分的代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int stair[11000][110],num[11000][110];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=0;j<m;j++)
scanf("%d%d",&stair[i][j],&num[i][j]);
}
int pos;
scanf("%d",&pos);
int ans;
for(int i=1;i<=n;i++){
int x=num[i][pos];
ans=(ans+x)%20123;
if(stair[i][pos]) --x;
while(x){
pos=(pos+1)%m;
if(stair[i][pos]) --x;
}
}
printf("%d\n",ans);
return 0;
}
很遗憾的是只有五十分,我们来分析一下为什么,观察一下测试的案例,对于百分之五十的数据,N,x的值并不大,然而对于百分之一百的数据,x的最大值来到了一百万,这就意味着最大的循环次数达到了n*x上亿的原子操作数,也就意味着时间复杂度过大了,那么我们就需要想办法优化一下时间复杂度,仔细观察,对于每一层的房间个数最大也就是100,然而x的最大值和房间个数差距也太大了,所以我们不妨考虑对x取模,x的值换成每层楼里面有楼梯通往下一层的房间的个数,这样,循环次数就会大大减小,那么接下来看一下我修改之后的代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int stair[10010][110],num[10010][110];
int ans,pos;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=0;j<m;j++){
scanf("%d%d",&stair[i][j],&num[i][j]);
}
}
scanf("%d",&pos);
for(int i=1;i<=n;i++){
int x=num[i][pos];
ans=(ans+x)%20123;
int t=0;
for(int j=0;j<m;j++)
t+=stair[i][j];
x%=t;
if(x==0) x=t;
if(stair[i][pos]) x--;
while(x){
pos=(pos+1)%m;
if(stair[i][pos]) --x;
}
}
printf("%d\n",ans);
return 0;
}
这样就完成了时间复杂度的优化,是能获得满分的代码。