首页 > 代码库 > Codeforces Round #380 (Div. 2) 总结分享

Codeforces Round #380 (Div. 2) 总结分享

B. Spotlights

  • 题意

  有n×m个格子的矩形舞台,每个格子里面可以安排一个演员或聚光灯,聚光灯仅可照射一个方向(俯视,上下左右)。若聚光灯能照到演员,则称为“good position”,求:共有多少“good position”(同一格子的不同照射方向算作不同的position)。

  • 思路

  对于一行而言,只要分别找到两侧第一个演员的位置(命名“标志位”),就能确定这一行的“good position”。两标志位以外的聚光灯只能投向一个方向(∵两标志位在同一侧),标志位之间的聚光灯能投向两个方向(即左右两侧的标志位)。因此,只要计算出两标志位以外的0元个数加上标志位之间0元个数×2就是这一行的“good position”的个数。列同理,然后全部相加即可。

  • 代码

技术分享
 1 #include <bits/stdc++.h>
 2 #define max_n 1001
 3 
 4 using namespace std;
 5 
 6 int n, m, r1[max_n], r2[max_n], c1[max_n], c2[max_n], r0[max_n], c0[max_n], ans;
 7 int main()
 8 {
 9     std::ios::sync_with_stdio(0);
10     cin >> n >> m;
11     int temp;
12     for(int i=1; i<=n; i++) { // 1e6
13         for(int j=1; j<=m; j++) {
14             cin >> temp;
15             if(temp) {
16                 if(!r1[i]) r1[i] = j;
17                 r2[i] = j;
18                 if(!c1[j]) c1[j] = i;
19                 c2[j] = i;
20             } else {
21                 r0[i]++;
22                 c0[j]++;
23             }
24         }
25     }
26     for(int i=1; i<=n; i++) { // 1e3
27         if(r1[i]!=0) {
28             int t = r1[i]-1+m-r2[i];
29             ans += 2*r0[i]-t;
30         }
31     }
32     for(int j=1; j<=m; j++) { // 1e3
33         if(c1[j]!=0) {
34             int t = c1[j]-1+n-c2[j];
35             ans += 2*c0[j]-t;
36         }
37     }
38     cout << ans;
39     return 0;
40 }
Unfold Code
  • 分析

  这里我没建立矩阵,因为录完数据之后,要遍历一次矩阵来找到标志位,感觉太费时间(可能是错觉。。。);所以我在录数据的时候就把标志位记录下来了;

  计算没什么好说的,最坑的是pretest中有一个专门卡时间的1000×1000,无数次TLE。完了之后查资料发现有一个方法可以加快cin读数据的速度(瞬间崩溃Orz),不过现在就知道了这个技巧。原来这种缓冲区超时是由于iostream的缓冲跟stdio的同步,导致cin读取速度很慢,用 std::ios::sync_with_stdio(false); 取消同步,加快速度,但是取消了之后,cin不能和stdio的输入(scanf,fscanf, getchar, fgets等)同时使用,不然可能导致输出与预期不一样,另外,cout尽量少加endl,也是防止超时!经测试,自从用了scanfprintf,妈妈再也不用担心我的缓冲区超时了!

  

由于本鶸水平有限,剩余题目日后再更!

 

Codeforces Round #380 (Div. 2) 总结分享