QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#346104#3201. Cairo CorridorPetroTarnavskyi#WA 1ms5732kbC++204.7kb2024-03-07 20:32:582024-03-07 20:32:58

Judging History

This is the latest submission verdict.

  • [2024-03-07 20:32:58]
  • Judged
  • Verdict: WA
  • Time: 1ms
  • Memory: 5732kb
  • [2024-03-07 20:32:58]
  • Submitted

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

const int N = 274;
const int N2 = N * N * 2;

int c[N2];
VI g[N2];
bool used[N2];
int val[N2];

int tin[N2];
int low[N2];
int par[N2];
int con[N2];
int T = 0;

int n, m;
	
int dfs(int v)
{
	used[v] = true;
	int res = val[v];
	for (auto to : g[v])
	{
		if (c[to] == 0 && !used[to])
			res |= dfs(to);
	}
	return res;
}

void dfs2(int v, int p = -1)
{
	used[v] = 1;
	par[v] = p;
	low[v] = tin[v] = T++;
	int cnt = 0;
	con[v] = 0;
	for (auto to : g[v])
	{
		if (to == p)
			continue;
		if (c[to] == 1)
			continue;
		if (!used[to])
		{
			cnt++;
			dfs2(to, v);
			
			low[v] = min(low[v], low[to]);
			
			if ((par[v] == -1 && cnt > 1) ||
				(par[v] != -1 && low[to] >= tin[v]))
					con[v] = 1;
		}
		else
		{
			low[v] = min(low[v], tin[to]);
		}
	}
}

void clear()
{
	FOR (i, 0, n * m)
	{
		val[i] = 0;
		c[i] = 0;
		used[i] = false;
		g[i].clear();
		low[i] = 0;
		tin[i] = 0;
		par[i] = 0;
		con[i] = 0;
	}
	T = 0;
}



void solve()
{
	cin >> n >> m;
	FOR (i, 0, n)
	{
		string s;
		cin >> s;
		FOR (j, 0, m)
		{
			c[i * 2 * m + j * 2] = s[j * 2] - '0';
			c[i * 2 * m + j * 2 + 1] =  s[j * 2 + 1] - '0';
		}
	}
	// v = i * m + j * 2 + (0 ? 1)
	FOR (i, 0, n)
	{
		FOR (j, 0, m)
		{
			if ((i + j) % 2 == 0)
			{
				int v1 = i * 2 * m + j * 2;
				int v2 = i * 2 * m + j * 2 + 1;
				g[v1].PB(v2);
				g[v2].PB(v1);
				if (i)
				{
					int u = (i - 1) * 2 * m + j * 2 + 1;
					g[v1].PB(u);
					g[v2].PB(u);
					g[u].PB(v1);
					g[u].PB(v2);
				}
				if (i + 1 < n)
				{
					int u = (i + 1) * 2 * m + j * 2;
					g[v1].PB(u);
					g[v2].PB(u);
					g[u].PB(v1);
					g[u].PB(v2);
				}
			}
			else
			{
				int v1 = i * 2 * m + j * 2;
				int v2 = i * 2 * m + j * 2 + 1;
				g[v1].PB(v2);
				g[v2].PB(v1);
				if (j)
				{
					int u = i * 2 * m + (j - 1) * 2 + 1;
					g[v1].PB(u);
					g[v2].PB(u);
					g[u].PB(v1);
					g[u].PB(v2);
				}
				if (j + 1 < m)
				{
					int u = i * 2 * m + (j + 1) * 2;
					g[v1].PB(u);
					g[v2].PB(u);
					g[u].PB(v1);
					g[u].PB(v2);
				}
			}
		}
	}
	// top
	FOR (j, 0, m)
	{
		if (j & 1)
			val[j * 2] |= 1;
		else
		{
			val[j * 2] |= 1;
			val[j * 2 + 1] |= 1;
		}
	}
	// left
	FOR (i, 0, n)
	{
		if (i & 1)
		{
			val[i * 2 * m] |= 2;
			val[i * 2 * m + 1] |= 2;
		}
		else
			val[i * 2 * m] |= 2;
	}
	// bottom
	int rws = (n + 1) & 1;
	FOR (j, 0, m)
	{
		if ((j & 1) ^ rws)
			val[(n - 1) * 2 * m + j * 2 + 1] |= 4;
		else
		{
			val[(n - 1) * 2 * m + j * 2] |= 4;
			val[(n - 1) * 2 * m + j * 2 + 1] |= 4;			
		}
	}
	// right
	int cls = (m + 1) & 1;
	FOR (i, 0, n)
	{
		if ((i & 1) ^ cls)
		{
			val[i * 2 * m + (m - 1) * 2] |= 8;
			val[i * 2 * m + (m - 1) * 2 + 1] |= 8;
		}
		else
			val[i * 2 * m + (m - 1) * 2 + 1] |= 8;
	}
	m *= 2;
	
	int v = -1;
	FOR (i, 0, n * m)
	{
		if (!used[i] && c[i] == 0)
		{
			int r = dfs(i);
			if (r == 15)
			{
				v = i;
				break;
			}
		}
	}
	fill(used, used + n * m, false);
	//cerr << v << '\n';
	//clear();
	//return;
	dfs(v);
	VI leaf;
	FOR (u, 0, n * m)
	{
		if (!used[u])
			continue;
		int cnt = 0;
		for (auto to : g[u])
		{
			if (used[to] && c[to] == 0)
				cnt++;
		}
		if (cnt == 1)
			leaf.PB(u);
	}
	//cerr << SZ(leaf) << '\n';
	if (SZ(leaf) > 4)
	{
		cout << "NO MINIMAL CORRIDOR\n";
		clear();
		return;
	}
	fill(used, used + n * m, false);
	dfs2(v);
	int cnt = 0;
	int all = 0;
	FOR (i, 0, n * m)
	{
		if (used[i] && !con[i])
			cnt++;
		all += used[i];
	}
	//cerr << SZ(leaf) << ' ' << cnt << '\n';
	assert(cnt >= SZ(leaf));
	if (cnt != SZ(leaf))
	{
		cout << "NO MINIMAL CORRIDOR\n";
		clear();
		return;		
	}
	bool ok = true;
	for (auto l : leaf)
	{
		c[l] = 1;
		fill(used, used + n * m, false);
		int u = v;
		if (v == l)
		{
			for (auto to : g[v])
				if (c[to] == 0)
					u = to;
			assert(u != v);
		}
		int x = dfs(u);
		if (x == 15)
			ok = false;
		//cerr << l << ' ' << v << ' ' << x << ' ' << ok << '\n';
		c[l] = 0;
	}
	clear();
	if (!ok)
	{
		cout << "NO MINIMAL CORRIDOR\n";
		return;		
	}
	else
		cout << all << '\n';
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
	
	return 0;
	
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3704kb

input:

2
6 6
010101001001
001000101100
110101001101
010010000100
001110110010
001001101010
6 6
010010110010
001100100111
000110100101
011001100101
100100011100
011010001101

output:

17
NO MINIMAL CORRIDOR

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 1ms
memory: 3672kb

input:

1
3 4
11110111
01000000
11110111

output:

9

result:

ok single line: '9'

Test #3:

score: -100
Wrong Answer
time: 1ms
memory: 5732kb

input:

7
1 1
00
1 1
10
1 1
01
2 1
00
00
2 1
10
00
3 1
10
00
01
3 1
10
00
00

output:

2
0
0
NO MINIMAL CORRIDOR
3
4
NO MINIMAL CORRIDOR

result:

wrong answer 2nd lines differ - expected: 'NO MINIMAL CORRIDOR', found: '0'