QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#117476#4884. Battleship: New Ruleshos_lyricRE 6ms3596kbC++145.6kb2023-07-01 12:11:462023-07-01 12:11:48

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-01 12:11:48]
  • 评测
  • 测评结果:RE
  • 用时:6ms
  • 内存:3596kb
  • [2023-07-01 12:11:46]
  • 提交

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;
      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;
        
        // 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;
          }
        }
        
        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: 3596kb

input:

2
3
1
4
1
1
0
1
0
0
0
1
1
0
0
0
1

output:

! -1 -1
? 1 1
? 1 2
? 1 3
? 1 4
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 4 2
? 3 2
? 3 3
! 2 2

result:

ok max_C=3.00, avg_C=1.50 (2 test cases)

Test #2:

score: 0
Accepted
time: 6ms
memory: 3596kb

input:

100
4
1
1
0
1
0
0
0
1
1
0
0
0
1
4
1
1
0
1
0
0
0
1
1
0
0
0
1
4
1
0
1
1
0
0
0
0
0
1
1
0
1
4
1
0
1
1
0
0
0
0
0
1
1
0
1
4
1
1
0
1
0
0
0
1
1
0
0
0
1
4
1
1
0
1
0
0
0
1
1
0
0
0
1
4
1
1
0
1
0
0
0
1
1
0
0
0
1
4
1
0
1
1
0
0
0
0
0
1
1
0
1
4
1
0
1
1
0
0
0
0
0
1
1
0
1
4
1
0
1
1
0
0
0
0
0
1
1
0
1
4
1
0
1
1
0
0
0
...

output:

? 1 1
? 1 2
? 1 3
? 1 4
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 4 2
? 3 2
? 3 3
! 2 2
? 1 1
? 1 2
? 1 3
? 1 4
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 4 2
? 3 2
? 3 3
! 2 2
? 1 1
? 1 2
? 1 3
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 3 2
? 4 1
? 4 2
? 3 3
! 2 2
? 1 1
? 1 2
? 1 3
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 3 2
? 4 1
? 4 2
...

result:

ok max_C=3.00, avg_C=3.00 (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
1
0
1
0
0
0
1
0
0
0
1
1
0
0
1
1
0
0
0
1
0
1
0
1
0
1
0
1
0
0
0
0
1
0
1
0
0
0
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
? 5 1
? 5 9
? 5 10
? 6 4
? 6 5
? 7 4
? 7 5
? 8 4
? 8 5
? 9 4
? 9 5
? 6 1
? 6 2
? 6 3
? 10 5
? 7 6
? 7 7
? 7 8
? 8 7
? 8 8
? 7 9
? 7 10
? 6 7
? 6 8
? 6 9
? 6 10
?...

result: