제출 #448351

#제출 시각아이디문제언어결과실행 시간메모리
448351cheissmartVirus Experiment (JOI19_virus)C++17
100 / 100
630 ms102972 KiB
#include <bits/stdc++.h>
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;

string to_string(char c) { return string(1, c); }
string to_string(bool b) { return b?"true":"false"; }
string to_string(const char* s) { return string(s); }
string to_string(string s) { return s; }
string to_string(V<bool> v) {
	string res;
	for(int i=0;i<(int)v.size();i++) res+=char('0'+v[i]);
	return res;
}
template<class T1, class T2> string to_string(pair<T1, T2> p) {return "(" + to_string(p.F) + ", " + to_string(p.S) + ")";}
template<size_t S> string to_string(bitset<S> b) {
	string res;
	for(int i=0;i<S;i++) res+=char('0'+b[i]);
	return res;
}
template<class T> string to_string(T v) {
    bool f=1;
    string res;
    for(auto x:v){
		if(!f) res+=' ';
		f=0; res+=to_string(x);
	}
    return res;
}



string _reset = "\u001b[0m", _yellow = "\u001b[33m", _bold = "\u001b[1m";
void DBG() { cerr << "]" << _reset << endl; }
template<class H, class...T> void DBG(H h, T ...t) {
	cerr << to_string(h);
	if(sizeof ...(t)) cerr << ", ";
	DBG(t...);
}
#ifdef CHEISSMART
#define debug(...) cerr << _yellow << _bold << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define debug(...)
#endif

const int INF = 1e9 + 7, N = 808;

string DIR = "NESW";
int di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1};

int a[N][N];
int r, c, m;
bool can[N][N][1 << 4];

int get_len(vi& v) {
	int mx = 0, cur = 0;
	for(int i:v) {
		if(i == 0) {
			mx = max(mx, cur);
			cur = 0;
		} else {
			cur++;
		}
	}
	mx = max(mx, cur);
	return mx;
}

pi p[N][N];
V<pi> rp[N][N];
bool dead[N][N];
pi who[N][N];

pi& P(pi u) { return p[u.F][u.S]; }
V<pi>& RP(pi u) { return rp[u.F][u.S]; }
pi& WHO(pi u) { return who[u.F][u.S]; }
bool& DEAD(pi u) { 
	u = WHO(P(u));
	return dead[u.F][u.S];
}

void unite(pi u, pi v) {
	u = P(u), v = P(v);
	if(u == v) return;
	debug(u.F, u.S, v.F, v.S);
	pi new_rep = WHO(v);
	if(RP(u).size() > RP(v).size()) swap(u, v);
	for(pi e:RP(u)) {
		RP(v).PB(e);
		P(e) = v;
	}
	RP(u).clear();
	WHO(v) = new_rep;
}

int vis[N][N], cnt = 0;

bool valid(int i, int j) {
	return 0 <= i && i < r && 0 <= j && j < c;
}

pair<pi, int> BFS(pi s) {
	assert(WHO(P(s)) == s);
	cnt++;
	int res = 0;
	queue<pi> q;
	pi x = {-1, -1};
	auto add = [&] (int i, int j) {
		assert(p[i][j] == P(s));
		assert(vis[i][j] != cnt);
		vis[i][j] = cnt;
		res++;
		q.push(MP(i, j));
	};
	auto check = [&] (int i, int j) {
		int mask = 0;
		for(int k = 0; k < 4; k++) {
			int ii = i + di[k], jj = j + dj[k];
			if(valid(ii, jj) && vis[ii][jj] == cnt) {
				mask |= 1 << k;
			}
		}
		return can[i][j][mask];
	};

	add(s.F, s.S);
	while(q.size()) {
		auto [i, j] = q.front(); q.pop();
		for(int k = 0; k < 4; k++) {
			int ii = i + di[k], jj = j + dj[k];
			if(valid(ii, jj) && vis[ii][jj] != cnt) {
				if(check(ii, jj)) {
					if(s == MP(2, 3)) {
						debug(ii, jj);
					}
					if(p[ii][jj] == P(s)) {
						add(ii, jj);
					} else {
						x = {ii, jj};
					}
				}
			}
		}
	}
	return {x, res};
}

signed main()
{
	IO_OP;

	string ds;
	cin >> m >> r >> c >> ds;

	vi d;
	for(char _:ds)
		d.PB(int(find(ALL(DIR), _) - DIR.begin()));

	for(int i = 0; i < r; i++)
		for(int j = 0; j < c; j++)
			cin >> a[i][j];

	for(int mask = 0; mask < (1 << 4); mask++) {
		vi td;
		for(int i:d) td.PB(mask >> i & 1);
		int len = INF;
		if(find(ALL(td), 0) != td.end()) {
			for(int i = 0; i < int(d.size()); i++)
				td.PB(td[i]);
			len = get_len(td);
		}
		for(int i = 0; i < r; i++) {
			for(int j = 0; j < c; j++) if(a[i][j] && a[i][j] <= len) {
				can[i][j][mask] = true;
			}
		}
	}
	for(int i = 0; i < r; i++) {
		for(int j = 0; j < c; j++) {
			who[i][j] = p[i][j] = {i, j};
			rp[i][j].EB(i, j);
		}
	}

	int ans = INF, cnt = 0;
	for(int _ = 0; _ < 100; _++) {
		V<pair<pi, pi>> todo;
		for(int i = 0; i < r; i++) for(int j = 0; j < c; j++) if(a[i][j]) {
			if(WHO(P(MP(i, j))) == MP(i, j) && !DEAD(MP(i, j))) {
				pair<pi, int> x = BFS({i, j});
				if(x.F.F == -1) { // no new
					if(x.S < ans) ans = x.S, cnt = x.S;
					else if(x.S == ans) cnt += x.S;
					debug(i, j, x, RP(MP(i, j)));
					DEAD(MP(i, j)) = true;
				} else {
					todo.EB(MP(i, j), x.F);
				}
			}
		}
		if(todo.empty()) break;
		for(auto [u, v] : todo)
			unite(u, v);
	}

	cout << ans << '\n' << cnt << '\n';

}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...