QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#117466 | #4884. Battleship: New Rules | hos_lyric | RE | 5ms | 3600kb | C++14 | 4.7kb | 2023-07-01 11:45:20 | 2023-07-01 11:45:21 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
int N;
#ifdef LOCAL
int secret[1010][1010];
#endif
int cache[1010][1010];
int A(int x, int y) {
assert(1 <= x); assert(x <= N);
assert(1 <= y); assert(y <= N);
int &ret = cache[x][y];
if (!~ret) {
printf("? %d %d\n", x, y);
fflush(stdout);
#ifdef LOCAL
ret = secret[x][y];
#else
scanf("%d", &ret);
if (!(ret == 0 || ret == 1)) {
exit(0);
}
#endif
}
return ret;
}
void Answer(int x, int y) {
printf("! %d %d\n", x, y);
fflush(stdout);
#ifdef LOCAL
if(!(x==-1&&y==-1)){
assert(1<=x);assert(x<N);
assert(1<=y);assert(y<N);
for(int dx=0;dx<2;++dx)for(int dy=0;dy<2;++dy)assert(!secret[x+dx][y+dy]);
}
#else
int verdict;
scanf("%d", &verdict);
if (verdict != 1) {
exit(0);
}
#endif
}
int main() {
int numCases;
scanf("%d", &numCases);
for (; numCases--; ) {
scanf("%d", &N);
#ifdef LOCAL
for(int x=1;x<=N;++x){
static char buf[1010];
scanf("%s",buf);
for(int y=1;y<=N;++y)secret[x][y]=buf[y-1]-'0';
}
#endif
for (int x = 0; x <= N + 1; ++x) for (int y = 0; y <= N + 1; ++y) {
cache[x][y] = -1;
}
if (N % 2 != 0) {
Answer(-1, -1);
} else {
/*
(x-1,y-1)-(x-1,y )
| (x,y) |
(x ,y-1)-(x ,y )
*/
// empty corner in [x0, y0] * [x1, y1]
int x0 = 0, x1 = N + 1;
int y0 = 0, y1 = N + 1;
for (; x0 <= x1 && y0 <= y1; ) {
// cerr<<"["<<x0<<", "<<y1<<"] * ["<<y0<<", "<<y1<<"]"<<endl;
const bool cutX = (x1 - x0 >= y1 - y0);
const int mid = cutX ? ((x0 + x1) / 2) : ((y0 + y1) / 2);
const int w0 = cutX ? y0 : x0;
const int w1 = cutX ? y1 : x1;
// find empty corner on mid
for (int w = w0; w <= w1; ++w) {
int x, y;
if (cutX) {
x = mid - 1;
y = w - 1;
} else {
x = w - 1;
y = mid - 1;
}
if ([&]() -> bool {
for (int dx = 0; dx < 2; ++dx) for (int dy = 0; dy < 2; ++dy) {
if (!(1 <= x + dx && x + dx <= N && 1 <= y + dy && y + dy <= N)) {
return false;
}
}
for (int dx = 0; dx < 2; ++dx) for (int dy = 0; dy < 2; ++dy) {
if (A(x + dx, y + dy)) {
return false;
}
}
return true;
}()) {
Answer(x, y);
goto found;
}
}
// parity of (# corner) on (x0, y0)'s side
int cnt = cutX ? ((mid - x0) * (y1 - y0 + 1)) : ((x1 - x0 + 1) * (mid - y0));
// surrounding ships
auto at = [&](int x, int y) -> int {
return (1 <= x && x <= N && 1 <= y && y <= N) ? A(x, y) : 0;
};
for (const int x : {x0, x1 + 1}) {
for (int y = y0 + 1, yy = y0 + 1; y <= y1; y = yy) {
for (; yy <= y1 && at(x, y) == at(x, yy); ++yy) {}
if (at(x, y)) {
cnt += (yy - y + 1);
}
}
}
for (const int y : {y0, y1 + 1}) {
for (int x = x0 + 1, xx = x0 + 1; x <= x1; x = xx) {
for (; xx <= x1 && at(x, y) == at(xx, y); ++xx) {}
if (at(x, y)) {
cnt += (xx - x + 1);
}
}
}
if (cnt & 1) {
(cutX ? x1 : y1) = mid - 1;
} else {
(cutX ? x0 : y0) = mid + 1;
}
}
assert(false);
found:{}
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3600kb
input:
2 3 1 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1
output:
! -1 -1 ? 1 1 ? 1 2 ? 1 3 ? 1 4 ? 2 1 ? 2 2 ? 3 1 ? 3 2 ? 3 3 ? 3 4 ? 4 2 ? 4 3 ? 2 3 ? 2 4 ? 4 4 ! 2 2
result:
ok max_C=3.75, avg_C=1.88 (2 test cases)
Test #2:
score: 0
Accepted
time: 5ms
memory: 3600kb
input:
100 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 4 1 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 4 1 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 4 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 4 1 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 4 1 0 1 1 0 0 1 0 1 1 0 ...
output:
? 1 1 ? 1 2 ? 1 3 ? 1 4 ? 2 1 ? 2 2 ? 3 1 ? 3 2 ? 3 3 ? 3 4 ? 4 2 ? 4 3 ? 2 3 ? 2 4 ? 4 4 ! 2 2 ? 1 1 ? 1 2 ? 1 3 ? 1 4 ? 2 1 ? 2 2 ? 3 1 ? 3 2 ? 3 3 ? 3 4 ? 4 2 ? 4 3 ? 2 3 ? 2 4 ? 4 4 ! 2 2 ? 1 1 ? 1 2 ? 1 3 ? 2 1 ? 3 1 ? 3 2 ? 4 1 ? 3 3 ? 3 4 ? 4 2 ? 4 3 ? 2 3 ? 2 4 ? 4 4 ? 2 2 ! 2 2 ? 1 1 ? 1 2 ...
result:
ok max_C=3.75, avg_C=3.75 (100 test cases)
Test #3:
score: -100
Dangerous Syscalls
input:
100 10 1 0 0 0 0 1 10 1 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 1 1
output:
? 4 1 ? 4 2 ? 4 3 ? 5 2 ? 5 3 ! 4 2 ? 4 1 ? 4 2 ? 4 3 ? 5 2 ? 5 3 ? 4 4 ? 4 5 ? 5 4 ? 4 6 ? 5 5 ? 4 7 ? 5 6 ? 4 8 ? 5 7 ? 5 8 ? 4 9 ? 4 10 ? 6 4 ? 6 5 ? 7 4 ? 7 5 ? 8 4 ? 8 5 ? 9 4 ? 9 5 ? 6 1 ? 6 2 ? 6 3 ? 6 6 ? 6 7 ? 6 8 ? 6 9 ? 6 10 ? 7 6 ? 7 7 ? 7 8 ? 8 7 ? 8 8 ? 7 9 ? 7 10 ? 8 6 ? 9 6 ? 10 6 ? ...