Codeforces Round #363 (Div. 2) B. One Bomb(前缀和 + 后缀和)

来源:互联网 发布:道路拥堵数据 编辑:程序博客网 时间:2024/06/04 19:35
B. One Bomb
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a description of a depot. It is a rectangular checkered field of n × m size. Each cell in a field can be empty (".") or it can be occupied by a wall ("*").

You have one bomb. If you lay the bomb at the cell (x, y), then after triggering it will wipe out all walls in the row x and all walls in the column y.

You are to determine if it is possible to wipe out all walls in the depot by placing and triggering exactly one bomb. The bomb can be laid both in an empty cell or in a cell occupied by a wall.

Input

The first line contains two positive integers n and m (1 ≤ n, m ≤ 1000) — the number of rows and columns in the depot field.

The next n lines contain m symbols "." and "*" each — the description of the field. j-th symbol in i-th of them stands for cell (i, j). If the symbol is equal to ".", then the corresponding cell is empty, otherwise it equals "*" and the corresponding cell is occupied by a wall.

Output

If it is impossible to wipe out all walls by placing and triggering exactly one bomb, then print "NO" in the first line (without quotes).

Otherwise print "YES" (without quotes) in the first line and two integers in the second line — the coordinates of the cell at which the bomb should be laid. If there are multiple answers, print any of them.

Examples
input
3 4.*.......*..
output
YES1 2
input
3 3..*.*.*..
output
NO
input
6 5..*....*..*****..*....*....*..
output
YES3 3

求出x,y处,竖直方向的墙的个数,水平墙的个数,然后相加是否大于等于所有墙的个数
X[x][y][0]代表从上往下,从左往右到达(x,y)处的墙的个数(包括(x,y)处),X[x][y][1],表示从下往上,从右往左到达(x,y)处的墙的个数(包括(x,y)处),然后我们只需要做的就是判断(x,y)处是否为墙,如果为墙,证明我的X[x][y]数组对(x,y)这个点多算了三次墙,所以要减去三,如果不为墙则不需要减去
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 1e3 + 5;int n, m;char O[MAXN][MAXN];int X[MAXN][MAXN][2][2];int main() {while(~scanf("%d%d", &n, &m)) {memset(X, 0, sizeof(X));int wallret = 0;for(int i = 0; i < n; i ++) {scanf("%s", O[i]);for(int j = 0; j < m; j ++) {if(O[i][j] == '*') wallret ++;}}for(int i = 0; i < n; i ++) {for(int j = 0; j < m; j ++) {if(O[i][j] == '*') {X[i][j][0][0] = j - 1 >= 0 ? X[i][j - 1][0][0] + 1 : 1;X[i][j][0][1] = i - 1 >= 0 ? X[i - 1][j][0][1] + 1 : 1;} else {X[i][j][0][0] = j - 1 >= 0 ? X[i][j - 1][0][0]: 0;X[i][j][0][1] = i - 1 >= 0 ? X[i - 1][j][0][1]: 0;}}}for(int i = n - 1; i >= 0; i --) {for(int j = m - 1; j >= 0; j --) {if(O[i][j] == '*') {X[i][j][1][0] = j + 1 < m ? X[i][j + 1][1][0] + 1 : 1;X[i][j][1][1] = i + 1 < n ? X[i + 1][j][1][1] + 1 : 1;} else {X[i][j][1][0] = j + 1 < m ? X[i][j + 1][1][0] : 0;X[i][j][1][1] = i + 1 < n ? X[i + 1][j][1][1] : 0;}}}bool flag = false;for(int i = 0; i < n; i ++) {if(flag) break;for(int j = 0; j < m; j ++) {int s = X[i][j][0][0] + X[i][j][0][1] + X[i][j][1][0] + X[i][j][1][1];if(O[i][j] == '*' && s - 3>= wallret || O[i][j] == '.' && s >= wallret) {flag = true;printf("YES\n");printf("%d %d\n", i + 1, j + 1);break;}}}if(!flag) printf("NO\n");}return 0;}


1 0