結果
問題 | No.5002 stick xor |
ユーザー | yowa |
提出日時 | 2018-05-27 00:41:53 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 784 ms / 1,000 ms |
コード長 | 7,767 bytes |
コンパイル時間 | 26,354 ms |
実行使用メモリ | 1,576 KB |
スコア | 43,679 |
最終ジャッジ日時 | 2018-05-27 00:42:21 |
ジャッジサーバーID (参考情報) |
judge9 / |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 757 ms
1,576 KB |
testcase_01 | AC | 758 ms
1,572 KB |
testcase_02 | AC | 712 ms
1,572 KB |
testcase_03 | AC | 776 ms
1,572 KB |
testcase_04 | AC | 695 ms
1,576 KB |
testcase_05 | AC | 689 ms
1,572 KB |
testcase_06 | AC | 754 ms
1,576 KB |
testcase_07 | AC | 697 ms
1,576 KB |
testcase_08 | AC | 698 ms
1,572 KB |
testcase_09 | AC | 784 ms
1,576 KB |
testcase_10 | AC | 710 ms
1,572 KB |
testcase_11 | AC | 746 ms
1,576 KB |
testcase_12 | AC | 737 ms
1,572 KB |
testcase_13 | AC | 697 ms
1,572 KB |
testcase_14 | AC | 781 ms
1,572 KB |
testcase_15 | AC | 675 ms
1,572 KB |
testcase_16 | AC | 705 ms
1,576 KB |
testcase_17 | AC | 763 ms
1,572 KB |
testcase_18 | AC | 696 ms
1,572 KB |
testcase_19 | AC | 738 ms
1,572 KB |
testcase_20 | AC | 703 ms
1,572 KB |
testcase_21 | AC | 702 ms
1,572 KB |
testcase_22 | AC | 701 ms
1,572 KB |
testcase_23 | AC | 766 ms
1,576 KB |
testcase_24 | AC | 688 ms
1,572 KB |
testcase_25 | AC | 687 ms
1,568 KB |
testcase_26 | AC | 764 ms
1,572 KB |
testcase_27 | AC | 705 ms
1,572 KB |
testcase_28 | AC | 779 ms
1,576 KB |
testcase_29 | AC | 709 ms
1,576 KB |
testcase_30 | AC | 683 ms
1,572 KB |
testcase_31 | AC | 662 ms
1,576 KB |
ソースコード
#include <iostream> #include <cstdlib> #include <string> #include <sstream> #include <vector> #include <queue> #include <set> #include <map> #include <iostream> #include <fstream> #include <unistd.h> #include <algorithm> #include <cmath> #include <cstdlib> #include <cassert> #include <cstring> #include "sys/time.h" using namespace std; #define HERE (cerr << "LINE: " << __LINE__ << " " << __FUNCTION__ << endl) typedef long long ll_t; typedef unsigned long long ull_t; #define DBG(x) cerr << #x << ": " << x << endl struct timeval timer_begin, timer_end; int timer_called; inline void timer_start() { timer_called++; gettimeofday(&timer_begin, NULL); } inline double timer_now() { timer_called++; gettimeofday(&timer_end, NULL); return timer_end.tv_sec - timer_begin.tv_sec + (timer_end.tv_usec - timer_begin.tv_usec)/1000000.0; } template<class T> const T& clamp(const T& v,const T& lo,const T& hi) { return (v < lo) ? lo : (v > hi) ? hi : v; } template<typename T> void assign_min_max(T& min,T& max,const T& x) { if (x < min) min = x; if (x > max) max = x; } unsigned int hash_function(unsigned long p) { // xor32() p ^= p<<7; p ^= p>>1; p ^= p<<25; unsigned int c = __builtin_popcount(p); return p<<c | p>>(32-c); } uint64_t hash_function64(uint64_t p) { // xor64() p ^= p<<16; p ^= p>>7; p ^= p<<39; uint64_t c = __builtin_popcount(p); return p<<c | p>>(64-c); } struct xor128_t { uint64_t x, y, z, w; xor128_t(int seed=0) : x(123456789^seed) , y(362436069), z(521288629), w(88675123) { for (int i=0; i<48; i++) get(); } void init(int seed) { x = 123456789^seed; y = 362436069; z = 521288629; w = 88675123; for (int i=0; i<48; i++) get(); } inline uint64_t get() { uint64_t t=(x^(x<<11)); x=y; y=z; z=w; return (w=(w^(w>>19))^(t^(t>>8))); } inline uint64_t get(unsigned int sz) { if (sz <= 1) return 0; uint64_t x; const uint64_t mask = (1<<(ilogb(sz-1)+1)) - 1; //cout << sz << " " << mask << endl; assert(mask >= (sz-1) && mask < 2*sz-1); do { x = get() & mask; } while (x >= sz); return x; } inline int64_t get(int beg,int end) { return get(end-beg) + beg; } double get_double() { static const double double_factor = 1.0 / (1.0 + 0xffffffffffffffffuLL); return get() * double_factor; } double get_norm() { double a = get_double(); double b = get_double(); return sqrt(-2*log(a)) * cos(2*M_PI*b); } double get_gamma(double a) { if (a < 1.0) { return get_gamma(1+a) * pow(get_double(), 1/a); } double d = a - 1/3.0; double c = 1/sqrt(9.0 * d); while (true) { double x = get_norm(); double uni = 1 - get_double(); double v = (1.0+c*x)*(1.0+c*x)*(1.0+c*x); if (v > 0 && log(uni) < 0.5 * x*x + d - d*v + d*log(v)) return d*v; } } template<typename T> void shuffle(vector<T>& v,int partial=-1) { int sz = v.size(); if (partial < 0 || partial > sz) partial = sz; for (int i=0; i<partial; i++) { swap(v[i], v[i + get(sz-i)]); } } }; template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "[ "; for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " ]"; return os; } template<typename T> ostream& operator<<(ostream& os, const set<T>& v) { os << "{ "; for(typename set<T>::const_iterator it=v.begin(); it!=v.end(); ++it) { if (it != v.begin()) os << ", "; os << *it; } os << " }"; return os; } template<typename T1,typename T2> ostream& operator<<(ostream& os, const pair<T1,T2>& v) { os << "[ " << v.first << ", " << v.second << "]"; return os; } #ifdef LOCAL double TIME_LIMIT_FACTOR = 0.55; #else double TIME_LIMIT_FACTOR = 1.0; #endif double TIME_LIMIT = TIME_LIMIT_FACTOR * 10.0; /* insert here */ int N, K; struct op_t { int x, y, L, d; op_t() {} op_t(int x,int y,int L,int d) : x(x), y(y), L(L), d(d) {} vector<int> to_v() const { if (d == 0) return {y+1, x+1, y+1, x+L}; else return {y+1, x+1, y+L, x+1}; } bool is_valid() const { if (d == 0) return (x >= 0 && x < N-L+1 && y >= 0 && y < N); else return (x >= 0 && x < N && y >= 0 && y < N-L+1); } }; void apply(vector<string>& A,const op_t op) { if (op.d == 0) { for (int i=0; i<op.L; i++) A[op.y][op.x+i] ^= 1; } else { for (int i=0; i<op.L; i++) A[op.y+i][op.x] ^= 1; } } int count_black(vector<string>& A,const op_t op) { int c = 0; if (op.d == 0) { for (int i=0; i<op.L; i++) c += (A[op.y][op.x+i] & 1); c += 2*(op.x == 0 || A[op.y][op.x-1] != A[op.y][op.x]); c += 2*(op.x+op.L == N || A[op.y][op.x+op.L] != A[op.y][op.x+op.L-1]); } else { for (int i=0; i<op.L; i++) c += (A[op.y+i][op.x] & 1); c += 2*(op.y == 0 || A[op.y-1][op.x] != A[op.y][op.x]); c += 2*(op.y+op.L == N || A[op.y+op.L][op.x] != A[op.y+op.L-1][op.x]); } return c; } int score(const vector<string>& A) { int c = 0; for (int y=0; y<N; y++) for (int x=0; x<N; x++) c += (A[y][x] == '0'); return c; } vector<op_t> solve(vector<string> A, const vector<int>& Ls) { vector<op_t> ops(K); vector<pair<int,int>> ord; for (int i=0; i<K; i++) ord.push_back(make_pair(-Ls[i], i)); //sort(ord.begin(), ord.end()); //for (int i=0; i<K; i++) { for (const auto& pa : ord) { int i = pa.second; int L = Ls[i]; op_t best_op; int best_c = 0; for (int y=0; y<N; y++) for (int x=0; x<N; x++) for (int d=0; d<2; d++) { op_t op(x, y, L, d); if (!op.is_valid()) continue; int c = count_black(A, op); if (c > best_c) { best_c = c; best_op = op; } } //ops.push_back(best_op); ops[i] = best_op; apply(A, best_op); } xor128_t rng(192993); for (int lp=0; lp<10; lp++) { for (int i=0; i<K; i++) { //for (int ii=0; ii<K; ii++) { //int i = rng.get(K); if (ops[i].L < 10-lp) continue; op_t best_op = ops[i]; apply(A, best_op); int best_c = count_black(A, best_op); int L = best_op.L; for (int y=0; y<N; y++) for (int x=0; x<N; x++) for (int d=0; d<2; d++) { op_t op(x, y, L, d); if (!op.is_valid()) continue; int c = count_black(A, op); if (c > best_c) { best_c = c; best_op = op; } } ops[i] = best_op; apply(A, best_op); } } return ops; } void run_testcases() { N = 60; K = 500; vector<int> L(K); vector<string> A(N, string(N, '0')); for (int seed=1000; seed<=1099; seed++) { xor128_t rng(seed); for (int i=0; i<K; i++) L[i] = rng.get(1, 25); for (int y=0; y<N; y++) for (int x=0; x<N; x++) A[y][x] = '0' + rng.get(2); int s0 = score(A); auto ops = solve(A, L); for (const auto& op : ops) apply(A, op); int s1 = score(A); cout << "seed: " << seed << endl; cout << "Score = " << s1 - s0 << endl; } } int main(int argc,const char *argv[]) { if (argc > 1) { run_testcases(); return 0; } cin >> N >> K; vector<int> L(K); for (int i=0; i<K; i++) cin >> L[i]; vector<string> A(N); for (int i=0; i<N; i++) { cin >> A[i]; A[i].resize(N); } int s0 = score(A); auto ret = solve(A, L); for (const auto& op : ret) apply(A, op); int s1 = score(A); cerr << "Score = " << s1 - s0 << endl; assert(ret.size() == K); for (int i=0; i<K; i++) { auto v(ret[i].to_v()); cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << endl; } }