結果
問題 | No.5002 stick xor |
ユーザー | kuuso1 |
提出日時 | 2018-05-26 06:38:03 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 6,441 bytes |
コンパイル時間 | 33,746 ms |
実行使用メモリ | 1,772 KB |
スコア | 0 |
最終ジャッジ日時 | 2018-05-26 06:39:05 |
ジャッジサーバーID (参考情報) |
judge8 / |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
testcase_25 | WA | - |
testcase_26 | WA | - |
testcase_27 | WA | - |
testcase_28 | WA | - |
testcase_29 | WA | - |
testcase_30 | WA | - |
testcase_31 | WA | - |
ソースコード
#include <iostream> #include <bits/stdc++.h> #include <time.h> #include <sys/timeb.h> #include <cstdio> #include <sys/time.h> using namespace std; #define ll long long #define uint unsigned int #define ulong unsigned long long int #define maxN 200 #define maxK 600 int N, K; int L[maxK]; int A[maxN][maxN]; int H, W; class Xor128{ private: uint x, y, z, w; public: void init(uint seed = 0){ x = 123456789; y = 362436069; z = 521288629; w = 88675123; z ^= seed; } Xor128(){init();} Xor128(uint seed){init(seed);} uint Next(){ uint t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } int Next(int ul){ return ul == 0 ? 0 : NextI(0,ul-1); } int NextI(int from,int to){ int mod=to-from+1; int ret=(int)(Next()%mod); return ret+from; } double NextD(){ return (Next() & 1048575) / 1048575.0; } }; class Timer{ public: Timer(){ cycle_per_sec = (ulong) 2.7e9; } void Start(){ begin_cycle = getCycle(); } double getTime(){ return (double)(getCycle() - begin_cycle) / cycle_per_sec; } int elapsedMilliseconds(){ return (int)( 1000 * getTime() ); } ulong getCycle(){ uint low, high; __asm__ volatile ("rdtsc" : "=a" (low), "=d" (high)); return ((ulong) low) | ((ulong) high << 32); } private: ulong begin_cycle; ulong cycle_per_sec; }; Timer T; ll Now(){return (ll) T.elapsedMilliseconds();} const int MD = 10; const int MASK = 0x3FF; int decR(int s){return s >> MD;} int decC(int s){return s & MASK;} int enc(int r,int c){return (r << MD) + c;} int dy[]{0, 1, 1, 1, 0, -1, -1, -1, 0,-2, 0,2}; int dx[]{1, 1, 0,-1, -1, -1, 0, 1, 2, 0,-2,0}; const double Inf = 1e18; const double Eps = 1e-9; bool InRange(int t, int l, int r){ return l <= t && t < r;} void Swap(int &a, int &b){ int t = a; a = b; b = t;} void Init(){ } void OutputSolution(vector<int> res){ for(int i=0;i<N;i++){ cout << (i + 1) << " " << (res[i] + 1) << endl; } } // SA template Xor128 lottery(25252525); const double C = 1000; inline bool SAgain(double score, double prev, long now, long start, long limitDuration){ if( score > prev ) return true; double ratio = - (prev - score) / prev; double remainingTime = (now - start) / (double) limitDuration; if( remainingTime > 1.0) return false; remainingTime = 1 - remainingTime; double acProb = exp(C * ratio / remainingTime); return (lottery.NextD() + Eps) < acProb ; } bool MCgain(double score, double prev, long now, long start, long limitDuration){ if( score > prev ) return true; return false; } int aa[maxN][maxN]; int calcScoreNaive(int ys[], int xs[], int ds[]){ for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ aa[i][j] = A[i][j]; } } for(int k=0;k<K;k++){ int x = xs[k]; int y = ys[k]; if(ds[k] == 0){ // vertical for(int i=y;i<y+L[k];i++) aa[i][x] ^= 1; } else { // horizontal for(int j=x;j<x+L[k];j++) aa[y][j] ^= 1; } } int sc = 0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) sc += aa[i][j]; sc = N * N - sc; return sc; } int maxSc = (int) -1e9; int maxY[maxN]; int maxX[maxN]; int maxD[maxN]; bool UpdateMax(int ys[], int xs[], int ds[], int sc, bool calc = false){ if(calc) sc = calcScoreNaive(ys, xs, ds); if(sc > maxSc){ maxSc = sc; for(int i=0;i<K;i++){ maxY[i] = ys[i]; maxX[i] = xs[i]; maxD[i] = ds[i]; } return true; } return false; } int a[maxN][maxN]; int xs[maxK]; int ys[maxK]; int ds[maxK]; void SA(ll tlimit){ ll tstart = Now(); ll timeLimitDuration = tlimit - tstart; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ a[i][j] = A[i][j]; } } Xor128 rnd(25252525); for(int i=0;i<K;i++){ xs[i] = rnd.Next(N - L[i] + 1); ys[i] = rnd.Next(N - L[i] + 1); ds[i] = rnd.Next(2); } for(int k=0;k<K;k++){ int x = xs[k]; int y = ys[k]; if(ds[k] == 0){ // vertical for(int i=y;i<y+L[k];i++) a[i][x] ^= 1; } else { // horizontal for(int j=x;j<x+L[k];j++) a[y][j] ^= 1; } } int sc = calcScoreNaive(ys, xs, ds); UpdateMax(ys, xs, ds, sc); ll cnt = 0; ll t1 = Now(); while(true){ cnt++; if(cnt % 100 == 0 && (t1 = Now()) - tstart > timeLimitDuration) break; int vh = rnd.Next(2); int pos = rnd.Next(K); int y = rnd.Next(vh == 0 ? N - L[pos] + 1 : N); int x = rnd.Next(vh == 1 ? N - L[pos] + 1 : N); int gain = 0; if(vh == 0){ // vertical int one = 0; int zero = 0; for(int i=y;i<y+L[pos];i++) one += a[i][x]; zero = L[pos] - one; gain = one - zero; } else { // horizontal int one = 0; int zero = 0; for(int j=x;j<x+L[pos];j++) one += a[y][j]; zero = L[pos] - one; gain = one - zero; } if(vh == 0){ // vertical for(int i=y;i<y+L[pos];i++) a[i][x] ^= 1; } else { // horizontal for(int j=x;j<x+L[pos];j++) a[y][j] ^= 1; } int lose = 0; if(ds[pos] == 0){ // vertical int one = 0; int zero = 0; for(int i=ys[pos];i<ys[pos]+L[pos];i++) one += a[i][xs[pos]]; zero = L[pos] - one; lose = one - zero; } else { // horizontal int one = 0; int zero = 0; for(int j=xs[pos];j<xs[pos]+L[pos];j++) one += a[ys[pos]][j]; zero = L[pos] - one; lose = one - zero; } if(ds[pos] == 0){ // vertical for(int i=ys[pos];i<ys[pos]+L[pos];i++) a[i][xs[pos]] ^= 1; } else { // horizontal for(int j=xs[pos];j<xs[pos]+L[pos];j++) a[ys[pos]][j] ^= 1; } int nsc = sc + gain + lose; if(SAgain(nsc, sc, t1, tstart, timeLimitDuration)){ sc = nsc; xs[pos] = x; ys[pos] = y; ds[pos] = vh; UpdateMax(ys, xs, ds, sc); } else { if(vh == 0){ // vertical for(int i=y;i<y+L[pos];i++) a[i][x] ^= 1; } else { // horizontal for(int j=x;j<x+L[pos];j++) a[y][j] ^= 1; } if(ds[pos] == 0){ // vertical for(int i=ys[pos];i<ys[pos]+L[pos];i++) a[i][xs[pos]] ^= 1; } else { // horizontal for(int j=xs[pos];j<xs[pos]+L[pos];j++) a[ys[pos]][j] ^= 1; } } } //Err("cnt: {0}", cnt); } void Solve(){ SA(900); for(int i=0;i<K;i++){ if(maxD[i] == 0){ printf("%d %d %d %d\n", maxY[i] + 1, maxX[i] + 1, maxY[i] + 1 + L[i] - 1, maxX[i] + 1); } else { printf("%d %d %d %d\n", maxY[i] + 1, maxX[i] + 1, maxY[i] + 1, maxX[i] + 1 + L[i] - 1); } } } int main(){ T.Start(); cin >> N >> K; for(int i=0;i<K;i++){ cin >> L[i]; } string s; for(int i=0;i<N;i++){ cin >> s; for(int j=0;j<N;j++){ A[i][j] = (int) (s[j] - '0'); } } Solve(); return 0; }