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 }
总结
这里有一个卡时间的输入数据1000×1000,若只用cin会造成缓冲区超时。缓冲区超时:由于iostream的缓冲跟stdio的同步,导致cin读取速度很慢,用 std::ios::sync_with_stdio(false); 取消同步,加快速度,但是取消了之后,cin不能和stdio的输入(scanf,fscanf, getchar, fgets等)同时使用,不然可能导致输出与预期不一样,另外,cout尽量少加endl,也是防止超时。所以:尽量使用scanf和printf

浙公网安备 33010602011771号