这道实际难度入门的题做得真™要麻烦死我,由于摸不到电脑,在大脑里调了3天都翻不转!!
思路:暴力模拟(这是基础,单纯暴力据说会全部TLE)+取模优化(这样时间复杂度骤降到O(NM))。
AC代码:
#include<bits/stdc++.h> using namespace std; long long n,m,t,a[10005][105],able[10005],start,ans,p; bool sign[10005][105]; int main() { scanf("%lld%lld",&n,&m); for(long long i=1; i<=n; i++) for(long long j=0; j<m; j++) { scanf("%lld%lld",&t,&a[i][j]); sign[i][j]=t; if(sign[i][j])able[i]++; } scanf("%lld",&start); long long j=start; for(long long i=1; i<=n; i++) { ans+=a[i][start]; p=a[i][start]%able[i]; if(p==0)p=able[i]; while(1) { if(sign[i][j])p--; if(!p)break; j++; if(j==m)j=0; } start=j; } ans=ans%20123; printf("%lld",ans); return 0; }
核心优化:
p=a[i][start]%able[i];
用start表示某一层楼的起点房间编号,able[]表示某一层具有楼梯的房间的数量,这句优化能够mod运算大大降低时间复杂度,比如:
某层楼有3个具有楼梯的房间,然而start房间的木牌上x=10000,暴力模拟需要走10000次,然而10000%3=1,走1次就可以了。
其实优化不是重点
关键是调对用于模拟的循环!
while(1) { if(sign[i][j])p--;//sign[][]是bool类型,记录房间是否具有楼梯 if(!p)break; j++; if(j==m)j=0;//模拟环形楼道 }
别忘了开long long
AC代码第一次提交拿了20分因为没看见答案要%20123