NC218050. 银杏林
描述
小 Y 每天上学和放学都会穿过这片银杏林。
银杏林可以看作一片 的矩形区域,上面有一些银杏树 用"T"表示,空地 用"."表示。
其中有一些的小路用字符 "R" 表示。
小 Y 很喜欢晒太阳,但树会挡住阳光,阳光无法穿过树。
解释:
的时候表示阳光从 给定矩形的左下方 射向 给定矩形的右上方
输入描述
第一行 给定
,
同题面。
第~
行给定
行长为
的字符串,其中
代表空地,
代表银杏树,
代表小路
第
行给定
表示询问数量。
为了方便描述,这里给出一种描述阳光方向的方法:对于每个询问给出两个整数表示阳光的方向,阳光方向即依次经过
,
的射线(方向是
指向
)。
请尽量自行联系描述以及上面的例子理解。
输出描述
对于每个询问,请输出一行一个整数即此时被阳光照到的 "R" 字符的数量。
示例1
输入:
3 3 TRR TRT RTT 3 2 1 0 1 1 0
输出:
2 1 1
说明:
下图中黄色点表示银杏树,绿色点表示小路,橙色线条代表阳光。
询问一:
询问二:
询问三:
示例2
输入:
3 3 TRR TRT RRT 3 1 2 1 1 0 1
输出:
1 4 4
示例3
输入:
3 3 TRR RRT RTT 4 -2 -1 -1 -2 -1 -1 -1 0
输出:
2 2 5 2
C++ 解法, 执行用时: 25ms, 内存消耗: 4248K, 提交时间: 2021-07-28 16:49:15
#include <stdio.h> #include <string.h> #define N 1005 int n, m, q, i, j, k, x, y, xx, yy, ans, c[N][N]; char s[N]; int cal(int xx, int yy){ int s = 0; while(xx<=m && yy<=n){ if(c[xx][yy] == 1) s++; if(c[xx][yy] < 0){ if(!k) break; else s = 0; } xx += x, yy += y; } return s; } int main(){ scanf("%d%d", &n, &m); for(i=0; i<n; i++){ scanf("%s", s+1); for(j=1; j<=m; j++){ if(s[j] == 'R') c[j][n-i] = 1; if(s[j] == 'T') c[j][n-i] = -1; } } scanf("%d", &q); while(q--){ scanf("%d%d", &x, &y); for(i=0; i<=n; i++) k = ans = 0; if(x < 0 || y < 0) k = 1, x = -x, y = -y; if(!x) y = 1; if(!y) x = 1; for(i=2; i<=x; i++){ while(x%i == 0 && y%i == 0) x /= i, y /= i; }//计算最近点(x, y) for(i=x; i<=m; i++) ans += cal(i, y); for(i=y+1; i<=n; i++) ans += cal(x, i); printf("%d\n", ans); } return 0; }