QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#137848 | #1283. Paper-cutting | mshcherba# | RE | 9ms | 11724kb | C++17 | 3.3kb | 2023-08-10 18:18:28 | 2023-08-10 18:19:22 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(), a.end()
#define FOR(i, a, b) for (int i = (a); i<(b); ++i)
#define RFOR(i, b, a) for (int i = (b)-1; i>=(a); --i)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define FILL(a, b) memset(a, b, sizeof(a))
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int mod[2] = {1'000'000'007, 1'000'000'009};
const int MAX = 1 << 20;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
struct Pair {
int a[2];
Pair(int x = 0) {
a[0] = a[1] = x;
}
Pair operator+(const Pair& p) const {
Pair res;
FOR(i, 0, 2) {
res.a[i] = (a[i] + p.a[i]) % mod[i];
}
return res;
}
Pair operator-(const Pair& p) const {
Pair res;
FOR(i, 0, 2) {
res.a[i] = (a[i] - p.a[i] + mod[i]) % mod[i];
}
return res;
}
Pair operator*(const Pair& p) const {
Pair res;
FOR(i, 0, 2) {
res.a[i] = (LL)a[i] * p.a[i] % mod[i];
}
return res;
}
bool operator==(const Pair& p) const {
return a[0] == p.a[0] && a[1] == p.a[1];
}
} pw[MAX];
vector<Pair> calcHash(const vector<Pair>& h) {
vector<Pair> res(SZ(h) + 1);
FOR(i, 0, SZ(h)) {
res[i + 1] = res[i] + pw[i] * h[i];
}
return res;
}
Pair getHash(const vector<Pair>& h, int l, int r) {
return (h[r + 1] - h[l]) * pw[MAX - 1 - r];
}
int fold(vector<Pair> h) {
vector<Pair> hDir = calcHash(h);
reverse(ALL(h));
vector<Pair> hRev = calcHash(h);
int i = 0;
FOR(j, 0, SZ(h)) {
int len = j - i + 1;
if (len <= SZ(h) - j - 1 && getHash(hDir, i, j) == getHash(hRev, SZ(h) - 1 - (j + len), SZ(h) - 1 - (j + 1))) {
i = j + 1;
}
}
return i;
}
void dfs(int i, int j, const vector<string>& s, int upperRow, int lowerRow, int leftCol, int rightCol, vector<vector<int>>& used) {
used[i][j] = true;
FOR(k, 0, 4) {
int ni = i + dx[k], nj = j + dy[k];
if (ni >= upperRow && ni <= lowerRow && nj >= leftCol && nj <= rightCol && s[ni][nj] == '0' && !used[ni][nj]) {
dfs(ni, nj, s, upperRow, lowerRow, leftCol, rightCol, used);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
pw[0] = 1;
FOR(i, 1, MAX) {
pw[i] = pw[i - 1] * 47;
}
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<string> s(n);
for (string& si : s) {
cin >> si;
}
vector<Pair> hRow(n);
FOR(i, 0, n) {
Pair pw2(1);
FOR(j, 0, m) {
if (s[i][j] == '1') {
hRow[i] = hRow[i] + pw2;
}
pw2 = pw2 * 2;
}
}
int upperRow = fold(hRow);
hRow = vector(hRow.begin() + upperRow, hRow.end());
reverse(ALL(hRow));
int lowerRow = upperRow + SZ(hRow) - 1 - fold(hRow);
vector<Pair> hCol(m);
FOR(j, 0, m) {
Pair pw2(1);
FOR(i, 0, n) {
if (s[i][j] == '1') {
hCol[j] = hCol[j] + pw2;
}
pw2 = pw2 * 2;
}
}
int leftCol = fold(hCol);
hCol = vector(hCol.begin() + leftCol, hCol.end());
reverse(ALL(hCol));
int rightCol = leftCol + m - 1 - fold(hCol);
vector used(n, vector<int>(m));
int ans = 0;
FOR(i, upperRow, lowerRow + 1) {
FOR(j, leftCol, rightCol + 1) {
if (s[i][j] == '0' && !used[i][j]) {
dfs(i, j, s, upperRow, lowerRow, leftCol, rightCol, used);
ans++;
}
}
}
cout << ans << "\n";
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 9ms
memory: 11724kb
input:
3 2 5 11001 11001 5 7 1001100 0110011 0101101 0010010 1000000 3 2 11 11 11
output:
1 4 0
result:
ok 3 tokens
Test #2:
score: -100
Runtime Error
input:
100000 3 3 010 101 101 4 2 10 10 10 10 4 2 11 00 00 11 7 1 1 0 0 1 1 0 0 6 1 1 0 0 1 1 1 5 2 11 00 00 11 11 10 1 1 0 0 0 0 0 0 0 0 1 9 1 0 0 0 0 0 0 0 0 0 10 1 1 1 1 1 1 1 1 1 1 0 9 1 0 0 0 0 0 0 1 1 0 1 10 0010000100 7 1 0 0 0 0 0 0 0 4 2 00 00 00 00 7 1 0 1 0 0 0 0 1 10 1 1 0 0 0 0 0 0 0 0 1 9 1 1...