QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#117480 | #4884. Battleship: New Rules | hos_lyric | RE | 7ms | 3748kb | C++14 | 5.9kb | 2023-07-01 12:28:05 | 2023-07-01 12:28:08 |
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=0;x<=N+1;++x)for(int y=0;y<=N+1;++y)secret[x][y]=0;
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';
}
int numAnss=0;
for(int x=0;x<=N;++x)for(int y=0;y<=N;++y){
int cnt=0;
for(int dx=0;dx<2;++dx)for(int dy=0;dy<2;++dy)cnt+=secret[x+dx][y+dy];
if(cnt==0)++numAnss;
}
assert(numAnss==((N%2!=0)?0:1));
#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;
int y0 = 0, y1 = N;
// int x0 = 1, x1 = N - 1;
// int y0 = 1, y1 = N - 1;
for (; x0 <= x1 && y0 <= y1; ) {
// cerr<<"["<<x0<<", "<<x1<<"] * ["<<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;
for (int w = w0; w <= w1; ++w) {
// corner (x, y) (on mid line) is empty?
int x, y;
if (cutX) {
x = mid;
y = w;
} else {
x = w;
y = mid;
}
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;
}
}
if ( cutX && !(x0 <= mid - 1)) { x0 = mid + 1; continue; }
if (!cutX && !(y0 <= mid - 1)) { y0 = mid + 1; continue; }
if ( cutX && !(mid + 1 <= x1)) { x1 = mid - 1; continue; }
if (!cutX && !(mid + 1 <= y1)) { y1 = mid - 1; continue; }
// parity of (# corner) on (x0, y0)'s side
const int x2 = cutX ? (mid - 1) : x1;
const int y2 = cutX ? y1 : (mid - 1);
int cnt = (x2 - x0 + 1) * (y2 - y0 + 1);
// 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, x2 + 1}) {
for (int y = y0 + 1, yy = y0 + 1; y <= y2; y = yy) {
for (; yy <= y2 && at(x, y) == at(x, yy); ++yy) {}
if (at(x, y)) {
// cerr<<" dy = "<<(yy-y+1)<<endl;
cnt -= (yy - y + 1);
}
}
}
for (const int y : {y0, y2 + 1}) {
for (int x = x0 + 1, xx = x0 + 1; x <= x2; x = xx) {
for (; xx <= x2 && at(x, y) == at(xx, y); ++xx) {}
if (at(x, y)) {
// cerr<<" dx = "<<(xx-x+1)<<endl;
cnt -= (xx - x + 1);
}
}
}
// if (at(x0 , y0 ) && !at(x0 + 1, y0 ) && !at(x0 , y0 + 1)) --cnt;
// if (at(x0 , y2 + 1) && !at(x0 + 1, y2 + 1) && !at(x0 , y2 )) --cnt;
// if (at(x2 + 1, y0 ) && !at(x2 , y0 ) && !at(x2 + 1, y0 + 1)) --cnt;
// if (at(x2 + 1, y2 + 1) && !at(x2 , y2 + 1) && !at(x2 + 1, y2 )) --cnt;
// cerr<<" ["<<x0<<", "<<x2<<"] * ["<<y0<<", "<<y2<<"]: "<<cnt<<endl;
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: 1ms
memory: 3676kb
input:
2 3 1 4 0 0 1 0 0 0 1
output:
! -1 -1 ? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2
result:
ok max_C=1.50, avg_C=0.75 (2 test cases)
Test #2:
score: 0
Accepted
time: 7ms
memory: 3748kb
input:
100 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 1 0 0 0 0 1 4 1 0 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 1 0 0 0 0 1 4 1 0 0 0 0 1 4 1 0 0 0 0 1 4 1 0 0 0 0 1 4 0 0 1 0 0 0 1 4 1 0 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 0 0 0 1 4 1 0 0 0 0 1 4 0 0 1 0 0 0 1 4 0 0 1 ...
output:
? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 3 1 ? 2 3 ? 3 2 ? 3 3 ! 2 2 ? 2 1 ? 2 2 ? 2 3 ...
result:
ok max_C=1.50, avg_C=1.37 (100 test cases)
Test #3:
score: -100
Dangerous Syscalls
input:
100 10 0 0 1 0 1 1 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 10 1 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 10 0 0 1 0 1 0 0 0 1 10 1 0 1 0 1 1 1 1 0 1 0 0 1 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 10 1 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 10 1 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 1 10...
output:
? 5 1 ? 5 2 ? 6 1 ? 5 3 ? 6 2 ? 5 4 ? 5 5 ? 5 6 ? 5 7 ? 5 8 ? 5 9 ? 5 10 ? 1 5 ? 2 5 ? 2 6 ? 3 5 ? 3 6 ? 4 5 ? 4 6 ? 2 1 ? 2 2 ? 2 3 ? 3 2 ? 3 3 ? 2 4 ? 3 4 ? 4 2 ? 4 3 ! 4 2 ? 5 1 ? 5 2 ? 5 3 ? 5 4 ? 5 5 ? 5 6 ? 5 7 ? 5 8 ? 5 9 ? 5 10 ? 6 5 ? 6 6 ? 7 5 ? 8 5 ? 8 6 ? 9 5 ? 6 1 ? 6 2 ? 6 3 ? 6 4 ? 10...