前几天惊闻上次那个《工程师死绝的世界》的社这回居然联动石头门出了个写代码游戏,我当即兴冲冲地跑去了。
去了之后先是注册账号,要 素 过 多。然后开始打,剧情看了几眼就没兴趣了,看知乎上说是什么你教labmem们写代码的。
前几题就纯普及组,可能唯一的障碍是读题。最后一题是个找环的,反正noip第一题难度,但是我WA了好几发,因为没特判自环其实不算一个环。
然后收集下面的乌帕,除了第二个之外都蛮简单,第二个巨NM阴间,题意是给你个30×30的矩阵,让你求一个权值和尽可能大的连通块。一下子把我们队三个都问住了,我问了学弟们,也不是很会的样子。然后我突然发现这几把题居然就是让你写非完美算法,草。这不得赶紧退火安排上。
还是有点不好退的。我一开始是初始每个位置1/2的概率选,然后调整。统计答案就是DFS一遍求最大的连通块,交上去41k,榜上最后一名是50k,我就想办法优化。后来想到初状态可以设置成所有为正的选,为负的不选。后来又想到可以设置成负的有1/2的几率选,这时已经优化到46k了。但是还是有问题,咋整,疯狂调参呗,但是还是调不上去。
这时我突然发现时限不是1s,然后我加大力度,把退火的温度变化量调小,马上就49k了,胜利近在眼前。之后也没想到啥靠谱的优化,就调随机种子,结果他给了我好运。他的生日是最好用的随机种子,直接51k上榜。我想着不如多随机几次,但是每次都没他高,我还发现我迟迟没上榜,仔细一看,这个榜居然不是取最高分数,而是取最新提交分数,大草。幸好我还记得那次的随机种子,重回51k了,截止目前是rank14。
1 /** 2 * There is no end though there is a start in space. ---Infinity. 3 * It has own power, it ruins, and it goes though there is a start also in the star. ---Finite. 4 * Only the person who was wisdom can read the most foolish one from the history. 5 * The fish that lives in the sea doesn't know the world in the land. 6 * It also ruins and goes if they have wisdom. 7 * It is funnier that man exceeds the speed of light than fish start living in the land. 8 * It can be said that this is an final ultimatum from the god to the people who can fight. 9 * 10 * Steins;Gate 11 **/ 12 13 #include <bits/stdc++.h> 14 typedef long long LL; 15 inline char gc() { 16 //return getchar(); 17 static char buf[100000], *p1 = buf, *p2 = buf; 18 if(p1 == p2) { 19 p2 = (p1 = buf) + fread(buf, 1, 100000, stdin); 20 } 21 return (p1 == p2) ? EOF : *p1++; 22 } 23 24 template <typename T> 25 inline void read(T& x) { 26 x = 0; 27 char c(gc()); 28 int f(1); 29 while(c < '0' || c > '9') { 30 if(c == '-') { 31 f = -1; 32 } 33 c = gc(); 34 } 35 while(c >= '0' && c <= '9') { 36 x = x * 10 + c - '0'; 37 c = gc(); 38 } 39 x *= f; 40 } 41 42 inline LL read() { 43 LL x; 44 read(x); 45 return x; 46 } 47 48 const int N = 32, INF = 0x3f3f3f3f; 49 50 const int dx[] = {0, 1, 0, -1}; 51 const int dy[] = {1, 0, -1, 0}; 52 53 int a[N][N], n, m, vis[N][N], fin, ans, tempans; 54 int Ans[N][N], dfn[N][N], tot, Ans2[N][N], top, X[900 * 1000 + 10], Y[900 * 1000 + 10], tpp; 55 56 const double oldT = 1000; 57 const double eps = 1e-4; 58 const double dT = 0.99995; 59 const int Time = 1; 60 61 inline int rd(int l, int r) { 62 return ((((LL)rand()) << 32) + rand()) % (r - l + 1) + l; 63 } 64 65 inline double Rand() { 66 return 1.0 * rand() / RAND_MAX; 67 } 68 69 inline bool valid(int x, int y) { 70 if(x < 1 || y < 1 || x > n || y > m || !vis[x][y] || dfn[x][y]) { 71 return false; 72 } 73 return true; 74 } 75 76 void DFS(int x, int y) { 77 dfn[x][y] = ++tot; 78 tempans += a[x][y]; 79 for(int i = 0; i < 4; i++) { 80 if(valid(x + dx[i], y + dy[i])) { 81 DFS(x + dx[i], y + dy[i]); 82 } 83 } 84 return; 85 } 86 87 void DFS2(int x, int y) { 88 dfn[x][y] = ++tot; 89 Ans2[x][y] = 1; 90 for(int i = 0; i < 4; i++) { 91 if(valid(x + dx[i], y + dy[i])) { 92 DFS2(x + dx[i], y + dy[i]); 93 } 94 } 95 return; 96 } 97 98 inline int cal() { 99 int ans = -INF; 100 tot = 0; 101 memset(dfn, 0, sizeof(dfn)); 102 for(int i = 1; i <= n; i++) { 103 for(int j = 1; j <= m; j++) { 104 if(!dfn[i][j] && vis[i][j]) { 105 tempans = 0; 106 DFS(i, j); 107 ans = std::max(ans, tempans); 108 } 109 } 110 } 111 return ans; 112 } 113 114 inline void init() { 115 memset(vis, 0, sizeof(vis)); 116 for(int i = 1; i <= n; i++) { 117 for(int j = 1; j <= m; j++) { 118 if(a[i][j] > 0) { 119 vis[i][j] = 1; 120 } 121 else { 122 vis[i][j] = rd(-1000, -1) <= a[i][j]; 123 } 124 } 125 } 126 ans = cal(); 127 // printf("ans = %d \n", ans); 128 if(ans > fin) { 129 fin = ans; 130 memcpy(Ans, vis, sizeof(Ans)); 131 } 132 return; 133 } 134 135 int main() { 136 137 srand(19260817); 138 read(n); 139 read(m); 140 for(int i = 1; i <= n; i++) { 141 for(int j = 1; j <= m; j++) { 142 read(a[i][j]); 143 if(a[i][j] < 0) { 144 ++top; 145 for(int k = 1000; k >= -a[i][j]; k--) { 146 X[++tpp] = i; 147 Y[tpp] = j; 148 } 149 } 150 } 151 } 152 153 if(top == 0) { 154 for(int i = 1; i <= n; i++) { 155 for(int j = 1; j <= m; j++) { 156 printf("1"); 157 } 158 puts(""); 159 } 160 return 0; 161 } 162 163 if(top == n * m) { 164 for(int i = 1; i <= n; i++) { 165 for(int j = 1; j <= m; j++) { 166 printf("0"); 167 } 168 puts(""); 169 } 170 return 0; 171 } 172 173 for(int A = 1; A <= Time; A++) { 174 double T = oldT; 175 init(); 176 while(T > eps) { 177 int id = rd(1, tpp); 178 int x = X[id], y = Y[id]; 179 vis[x][y] ^= 1; 180 int New = cal(); 181 if(New > fin) { 182 fin = New; 183 memcpy(Ans, vis, sizeof(vis)); 184 } 185 if(New > ans || Rand() < exp((New - ans) / T)) { 186 ans = New; 187 } 188 else { 189 vis[x][y] ^= 1; 190 } 191 T *= dT; 192 } 193 } 194 tot = 0; 195 memset(dfn, 0, sizeof(dfn)); 196 memcpy(vis, Ans, sizeof(Ans)); 197 for(int i = 1; i <= n; i++) { 198 for(int j = 1; j <= m; j++) { 199 if(!dfn[i][j] && vis[i][j]) { 200 tempans = 0; 201 DFS(i, j); 202 if(tempans == fin) { 203 // find 204 memset(dfn, 0, sizeof(dfn)); 205 206 tot = 0; 207 DFS2(i, j); 208 // out 209 for(int I = 1; I <= n; I++) { 210 for(int J = 1; J <= m; J++) { 211 printf("%d", Ans2[I][J]); 212 } 213 puts(""); 214 } 215 exit(0); 216 } 217 } 218 } 219 } 220 221 for(int i = 1; i <= n; i++) { 222 for(int j = 1; j <= m; j++) { 223 printf("0"); 224 } 225 puts(""); 226 } 227 //printf("%d\n", fin); 228 puts("FUCK!!!"); 229 return 0; 230 }