結果
問題 | No.5002 stick xor |
ユーザー | kuuso1 |
提出日時 | 2018-05-26 00:49:33 |
言語 | C#(csc) (csc 3.9.0) |
結果 |
AC
|
実行時間 | 924 ms / 1,000 ms |
コード長 | 9,056 bytes |
コンパイル時間 | 35,860 ms |
実行使用メモリ | 20,220 KB |
スコア | 36,449 |
最終ジャッジ日時 | 2018-05-26 00:50:14 |
ジャッジサーバーID (参考情報) |
judge9 / |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 921 ms
18,044 KB |
testcase_01 | AC | 922 ms
18,048 KB |
testcase_02 | AC | 922 ms
16,016 KB |
testcase_03 | AC | 920 ms
15,968 KB |
testcase_04 | AC | 922 ms
16,128 KB |
testcase_05 | AC | 921 ms
18,000 KB |
testcase_06 | AC | 921 ms
18,168 KB |
testcase_07 | AC | 923 ms
16,000 KB |
testcase_08 | AC | 924 ms
18,092 KB |
testcase_09 | AC | 921 ms
16,000 KB |
testcase_10 | AC | 921 ms
16,000 KB |
testcase_11 | AC | 921 ms
20,056 KB |
testcase_12 | AC | 922 ms
16,000 KB |
testcase_13 | AC | 922 ms
20,220 KB |
testcase_14 | AC | 921 ms
18,048 KB |
testcase_15 | AC | 922 ms
16,044 KB |
testcase_16 | AC | 921 ms
16,028 KB |
testcase_17 | AC | 921 ms
20,092 KB |
testcase_18 | AC | 923 ms
16,044 KB |
testcase_19 | AC | 924 ms
18,044 KB |
testcase_20 | AC | 922 ms
18,052 KB |
testcase_21 | AC | 922 ms
20,104 KB |
testcase_22 | AC | 921 ms
18,016 KB |
testcase_23 | AC | 920 ms
18,056 KB |
testcase_24 | AC | 922 ms
18,044 KB |
testcase_25 | AC | 921 ms
16,020 KB |
testcase_26 | AC | 921 ms
16,152 KB |
testcase_27 | AC | 921 ms
16,036 KB |
testcase_28 | AC | 921 ms
18,064 KB |
testcase_29 | AC | 921 ms
20,104 KB |
testcase_30 | AC | 921 ms
20,092 KB |
testcase_31 | AC | 922 ms
16,052 KB |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 2.3.1.61919 (57c81319) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
//#define DEBUG //#undef DEBUG using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text; using System.Diagnostics; #if DEBUG using System.Threading; #endif public class StickXor{ #region field int N, K; int[][] A; int[] L; #endregion void Solve(){ var d = ria(); N = d[0]; K = d[1]; L = ria(); A = new int[N][]; for(int i=0;i<N;i++){ A[i] = rs().Select(c => (int)(c - '0')).ToArray(); } SA(900); var sb = new StringBuilder(); for(int i=0;i<K;i++){ if(maxD[i] == 0){ sb.AppendLine(String.Format("{0} {1} {2} {3}", maxY[i] + 1, maxX[i] + 1, maxY[i] + 1 + L[i] - 1, maxX[i] + 1)); } else { sb.AppendLine(String.Format("{0} {1} {2} {3}", maxY[i] + 1, maxX[i] + 1, maxY[i] + 1, maxX[i] + 1 + L[i] - 1)); } } Console.Write(sb.ToString()); } int maxSc = (int) -1e9; int[] maxY = null; int[] maxX = null; int[] maxD = null; bool UpdateMax(int[] ys, int[] xs, int[] ds, int sc, bool calc = false){ if(calc) sc = calcScoreNaive(ys, xs, ds); //Err("sc: {0}, naive: {1}", sc, calcScoreNaive(ys, xs, ds)); //Debug.Assert(sc == calcScoreNaive(ys, xs, ds)); if(sc > maxSc){ //Err("update: minSc:{0} -> {1} : {2} [ms]",maxSc, sc, Now()); maxSc = sc; maxY = (int[]) ys.Clone(); maxX = (int[]) xs.Clone(); maxD = (int[]) ds.Clone(); return true; } return false; } void SA(long tlimit){ long tstart = Now(); long timeLimitDuration = tlimit - tstart; int[][] a = new int[N][]; for(int i=0;i<N;i++){ a[i] = new int[N]; for(int j=0;j<N;j++){ a[i][j] = A[i][j]; } } var rnd = new Xor128(25252525); int[] xs = new int[K]; int[] ys = new int[K]; int[] ds = new int[K]; 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++){ var x = xs[k]; var 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); long cnt = 0; long t1 = Now(); while(true){ cnt++; if(cnt % 100 == 0 && (t1 = Now()) - tstart > timeLimitDuration) break; var vh = rnd.Next(2); var pos = rnd.Next(K); var y = rnd.Next(N - L[pos] + 1); var x = rnd.Next(N - L[pos] + 1); 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; } var 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); } #region del #endregion int calcScoreNaive(int[] ys, int[] xs, int[] ds){ int[][] a = new int[N][]; for(int i=0;i<N;i++){ a[i] = new int[N]; for(int j=0;j<N;j++){ a[i][j] = A[i][j]; } } for(int k=0;k<K;k++){ var x = xs[k]; var 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 = 0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) sc += a[i][j]; sc = N * N - sc; return sc; } #region SA-Template static Xor128 lottery = new Xor128(25252525); const double C = 2800; static 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 = Math.Exp(C * ratio / remainingTime); return (lottery.NextD() + Eps) < acProb ; } static bool MCgain(double score, double prev, long now, long start, long limitDuration){ if( score > prev ) return true; return false; } static bool SAlose(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 = Math.Exp(C * ratio / remainingTime); return (lottery.Next(1000000) / 1000000.0 + Eps) < acProb ; } static bool MClose(double score, double prev, long now, long start, long limitDuration){ if( score < prev ) return true; return false; } #endregion #region TimeCount static Stopwatch sw = new Stopwatch(); static bool TU=false; static long TimeLimit=950; static bool TimeUp(){ if(TU){return true;} return TU = (sw.ElapsedMilliseconds>TimeLimit); } static long Now(){return sw.ElapsedMilliseconds;} static bool TUT=false; static long TimeLimitT=3000000; static bool TimeUpT(){ if(TUT){return true;} return TUT=(sw.ElapsedTicks>TimeLimitT); } static long NowT(){return sw.ElapsedTicks;} static void TimeStamp(String title){ Console.Error.WriteLine("{0}:{1} [ms]",title,Now()); } #endregion #region Decode const int MD = 10; const int MASK = 0x2FF; static int decR(int s){return s >> MD;} static int decC(int s){return s & MASK;} static int enc(int r,int c){return (r << MD) + c;} static int[] dy=new int[]{0, -1, 0, 1, 1, -1, -1, 1}; static int[] dx=new int[]{1, 0, -1, 0, 1, 1, -1, -1}; const double Inf = 1e18; const double Eps = 1e-9; static int D2(int x0, int y0, int x1, int y1){ x1 -= x0; y1 -= y0; return x1 * x1 + y1 * y1; } static double D(int x0, int y0, int x1, int y1){ return Math.Sqrt(D2(x0, y0, x1, y1)); } #endregion bool InRange(int t, int l, int r){ return l <= t && t < r;} void Swap<T> (ref T a, ref T b) { T t = a; a = b; b = t;} bool NextPermutation<T>(T[] a)where T:IComparable<T>{ for(int i=a.Length-2;i>=0;i--){ if(a[i].CompareTo(a[i+1])<0){ int trgt=Array.FindLastIndex(a,x=>a[i].CompareTo(x)<0); Swap(ref a[i],ref a[trgt]); Array.Reverse(a,i+1,a.Length-(i+1)); return true; } } Array.Reverse(a); return false; } static void Err(String format, params object[] args){ Console.Error.WriteLine(format, args); } static int seed = 0; public static void Main(){ //seed = int.Parse(args[0]); //C = double.Parse(args[1]); sw.Start(); var sx = new StickXor(); sx.Solve(); } static String rs(){return Console.ReadLine();} static int ri(){return int.Parse(Console.ReadLine());} static long rl(){return long.Parse(Console.ReadLine());} static double rd(){return double.Parse(Console.ReadLine());} static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);} static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));} static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));} static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));} } #if DEBUG static class DebugClass{ } #endif class Xor128{ uint x = 123456789; uint y = 362436069; uint z = 521288629; uint w = 88675123; const double div = 1.0 / 1048575.0; public Xor128(){ } public Xor128(uint seed){ z ^= seed; } public uint Next(){ uint t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } public int Next(int ul){ return ul == 0 ? 0 : NextI(0,ul-1); } public int NextI(int from,int to){ int mod=to-from+1; int ret=(int)(Next()%mod); return ret+from; } public double NextD(){ return (Next() & 1048575) * div; } }