洛谷 P1076 寻宝(模拟 && 剪枝)

嗯...

题目链接:https://www.luogu.org/problem/P1076

这道题的题意首先太难理解...并且细节太多...

可以用b[i][j]记录每个指示牌上的数字,a[i][j]记录是否有楼梯。那我们开一个ans,每次到达一个门就ans+=a[i][j](如果有楼梯,a[i][j]=1,ans就加了1,如果没有楼梯,a[i][j]=0,ans加的就是0,相当于没加),当ans=一开始指示牌上的数字时,退出循环。

————并且正解要剪枝——————

用c[i]记录第i层一共的楼梯数,每次循环时,若b[i][j]的数字大于这层楼的总楼梯数,则将b[i][j] % c[i](相当于他已经走了b[i][j] / c[i]圈了),这可以避免很多不必要计算。

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 
 4 using namespace std;
 5 
 6 int n, m, a[10005][105], b[10005][105], sum, k, ans, q, c[10005];
 7 
 8 int main(){
 9     scanf("%d%d", &n, &m);
10     for(int i = 1; i <= n; i++){
11         for(int j = 0; j < m; j++){
12             scanf("%d%d", &a[i][j], &b[i][j]);
13             c[i] += a[i][j];
14         }
15     }
16     scanf("%d", &k);
17     for(int i = 1; i <= n; i++){
18         sum += b[i][k];
19         ans = 0;
20         q = k;
21         b[i][q] = (b[i][q] - 1) % c[i] + 1;
22         while(ans < b[i][q]){
23             ans += a[i][k];
24             if(ans == b[i][q]) break;
25             k++;
26             if(k == m) k = 0;
27         }
28     }
29     printf("%d\n", sum % 20123);
30     return 0;
31 }
AC代码

猜你喜欢

转载自www.cnblogs.com/New-ljx/p/11837665.html