電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_i++

電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_其他_02

電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_i++_03

前几天惊闻上次那个《工程师死绝的世界》的社这回居然联动石头门出了个写代码游戏,我当即兴冲冲地跑去了。

去了之后先是注册账号,要 素 过 多。然后开始打,剧情看了几眼就没兴趣了,看知乎上说是什么你教labmem们写代码的。

前几题就纯普及组,可能唯一的障碍是读题。最后一题是个找环的,反正noip第一题难度,但是我WA了好几发,因为没特判自环其实不算一个环。

然后收集下面的乌帕,除了第二个之外都蛮简单,第二个巨NM阴间,题意是给你个30×30的矩阵,让你求一个权值和尽可能大的连通块。一下子把我们队三个都问住了,我问了学弟们,也不是很会的样子。然后我突然发现这几把题居然就是让你写非完美算法,草。这不得赶紧退火安排上。

还是有点不好退的。我一开始是初始每个位置1/2的概率选,然后调整。统计答案就是DFS一遍求最大的连通块,交上去41k,榜上最后一名是50k,我就想办法优化。后来想到初状态可以设置成所有为正的选,为负的不选。后来又想到可以设置成负的有1/2的几率选,这时已经优化到46k了。但是还是有问题,咋整,疯狂调参呗,但是还是调不上去。

这时我突然发现时限不是1s,然后我加大力度,把退火的温度变化量调小,马上就49k了,胜利近在眼前。之后也没想到啥靠谱的优化,就调随机种子,结果他给了我好运。他的生日是最好用的随机种子,直接51k上榜。我想着不如多随机几次,但是每次都没他高,我还发现我迟迟没上榜,仔细一看,这个榜居然不是取最高分数,而是取最新提交分数,大草。幸好我还记得那次的随机种子,重回51k了,截止目前是rank14。

電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_fish_04電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_娱乐_05
  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 }
51k代码

電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_fish_06電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_其他_07電脳言語のオルダーソンループ / ネット・ガーディアンの奮闘_其他_08