QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#117450#4884. Battleship: New Ruleshos_lyricRE 1ms3792kbC++144.3kb2023-07-01 11:09:032023-07-01 11:09:06

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 11:09:06]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3792kb
  • [2023-07-01 11:09:03]
  • 提交

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 {
      int x0 = 1, x1 = N + 1;
      int y0 = 1, 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;
        auto at = [&](int z, int w) -> int {
          return cutX ? A(mid - 1 + z, w) : A(w, mid - 1 + z);
        };
        auto asked = [&](int z, int w) -> bool {
          return cutX ? (~cache[mid - 1 + z][w]) : (~cache[w][mid - 1 + z]);
        };
        
        for (int z = 0; z < 2; ++z) for (int w = w0; w < w1; ++w) {
          at(z, w);
        }
        for (int z = -1; z < 2; ++z) for (int w = w0 - 1; w < w1; ++w) {
          if ([&]() -> bool {
            for (int dz = 0; dz < 2; ++dz) for (int dw = 0; dw < 2; ++dw) {
              if (!asked(z + dz, w + dw)) {
                return false;
              }
            }
            for (int dz = 0; dz < 2; ++dz) for (int dw = 0; dw < 2; ++dw) {
              if (at(z + dz, w + dw)) {
                return false;
              }
            }
            return true;
          }()) {
            cutX ? Answer(mid - 1 + z, w) : Answer(w, mid - 1 + z);
            goto found;
          }
        }
        
        // parity of (# corner) on (x0, y0)'s side
        int cnt = cutX ? ((mid - x0) * (y1 - y0 + 1)) : ((x1 - x0 + 1) * (mid - y0));
        for (int w = w0, ww = w0; w < w1; w = ww) {
          for (; ww < w1 && at(0, w) == at(0, ww); ++ww) {}
          if (at(0, w)) {
            cnt += (ww - w + 1);
          }
        }
        cnt &= 1;
        if (cnt & 1) {
          (cutX ? x1 : y1) = mid - 1;
        } else {
          (cutX ? x0 : y0) = mid + 1;
        }
      }
      assert(false);
     found:{}
    }
  }
  return 0;
}

详细

Test #1:

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

input:

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

output:

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

result:

ok max_C=2.00, avg_C=1.00 (2 test cases)

Test #2:

score: 0
Accepted
time: 0ms
memory: 3604kb

input:

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

output:

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

result:

ok max_C=2.00, avg_C=2.00 (100 test cases)

Test #3:

score: -100
Dangerous Syscalls

input:

100
10
0
0
0
1
0
1
0
1
0
1
1
1
0
1
0
1
0
1
0
1
1
0
0
0
1
0
1
1
1
0
0
0
1
0
1
1
0
0
1
10
1
0
1
1
1
1
0
1
0
1
1
0
0
0
0
0
0
1
0
1
1
0
1
1
1
0
0
0
0
1
0
1
0
0
0
0
1
10
0
0
0
0
1
1
0
1
0
1
1
1
0
0
0
0
0
1
0
1
1
10
1
0
1
0
1
1
1
1
0
1
1
0
1
0
0
0
0
0
0
0
1
1
0
1
0
0
0
1
1
0
0
0
0
0
0
1
1
10
1
0
0
0
1
0
0...

output:

? 5 1
? 5 2
? 5 3
? 5 4
? 5 5
? 5 6
? 5 7
? 5 8
? 5 9
? 5 10
? 6 1
? 6 2
? 6 3
? 6 4
? 6 5
? 6 6
? 6 7
? 6 8
? 6 9
? 6 10
? 1 5
? 2 5
? 3 5
? 4 5
? 1 6
? 2 6
? 3 6
? 4 6
? 2 1
? 2 2
? 2 3
? 2 4
? 3 1
? 3 2
? 3 3
? 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...

result: