Aya Code Golf A~E 本人代码
下面公布自己在 Aya Code Golf 中 A~E 题的赛时(和赛后)代码。它们很可能不是最优的。
允许将本文中的代码(优化后)提交至 滴叉 Code Golf,但是要求提交后将修改后的代码发送给我或公布。
A
憨憨作者读漏了牌已经排好序的条件。
char s[99],*i;x,d,c,f;main(e){gets(s);while(gets(s)){x=d=e=0;for(c=99;c--&&e<4;)for(e=0,i=s+17;i--!=s;x|=*i==88,d|=*i==68)e+=*i==c;puts(e>3||x&d?"yes":"no");}}
格式化后:
char s[99], *i;
x, d, c, f; // 无类型说明的全局变量默认为 int
main(e){ // main 可以省略 int,参数的 int 也可以省
gets(s);
while (gets(s)){
x = d = e = 0;
for (c = 99; c-- && e < 4;)
// 枚举每个字符,如果上个字符出现次数达到 4 就退出
for (e = 0, i = s + 17; i-- != s; x |= *i == 88, d |= *i == 68)
// 枚举每张牌,并判断其是不是大小王
e += *i == c;
puts(e > 3 || x & d ? "yes" : "no");
}
}
B
a[1<<21],i=8,j,k,s,l;main(T){while(i--)for(j=10;j--;a[(21<<i*2)+(2<<j*2)]=1);scanf("%d",&T);while(T--){for(l=s=0,i=4;i--;s+=1<<j*2)scanf("%d",&j);for(k=10;k--;)l|=a[s+(1<<k*2)];puts("0\0001"+l*2);}}
格式化后:
a[1 << 21], i = 8, j, k, s, l;
main(T) {
while (i--)
for (j = 10; j--; a[(21 << i * 2) + (2 << j * 2)] = 1); // 先求出所有符合题意的五元组,用四进制数记下来
scanf("%d", &T);
while (T--) {
for (l = s = 0, i = 4; i--; s += 1 << j * 2)
scanf("%d", &j); // 读入
for (k = 10; k--;)
l |= a[s + (1 << k * 2)]; // 枚举第五张牌
puts("0\0001" + l * 2);
// 画 蛇 添 足,puts(l?"1":"0"); 更短
}
}
C
long s;main(m){for(scanf("%*d");~scanf("%ld %d",&s,&m);printf(m<2||s&1?"-1\n":"2 %ld %ld\n",s/2,s/2));}
格式化后:
long s;
main(m) {
for (scanf("%*d"); // * 表示读入后丢弃
~scanf("%ld %d", &s, &m); // 返回 -1 代表读不动
printf(m < 2 || s & 1 ? "-1\n" : "2 %ld %ld\n", s / 2, s / 2)); // 简单构造
}
赛后代码:
long s;main(m){for(scanf("%*d");~scanf("%ld%d",&s,&m);printf(m<2|s&1?"-1\n":"2 %ld %ld\n",s/2,s/2));}
D
M=1e9+7,a[1<<20],i,X=1e9,Y=1;main(n){scanf("%d",&n);for(;i++^n;)scanf("%d",a+i),X=X<a[i]?X:a[i];for(;--i;)Y=a[i]/X*1l*Y%M;printf("%d %d",X,Y);}
格式化后:
// 不是很难看懂
M = 1e9 + 7, a[1 << 20], i, X = 1e9, Y = 1;
main(n) {
scanf("%d", &n);
for (; i++ ^ n;)
scanf("%d", a + i), X = X < a[i] ? X : a[i];
for (; --i;)
Y = a[i] / X * 1l * Y % M;
printf("%d %d", X, Y);
}
E
#include<bits/stdc++.h>
#define W(p) for(int i:d)a+=p abs(H[x]-H[x+i]);
using namespace std;map<long,long>H;unsigned long a,x,y,z;vector d{1,-1,1<<30,-1<<30};main(){cin>>x;while(cin>>x>>y>>z){x=x<<30|y;W(-);H[x]+=z;W();cout<<a<<"\n";}}
格式化后:
#include <bits/stdc++.h>
#define W(p) \
for (int i : d) \
a += p abs(H[x] - H[x + i]); // p 为符号
using namespace std;
map<long, long> H; // 横纵坐标压到一个数
unsigned long a, x, y, z;
vector d{1, -1, 1 << 30, -1 << 30}; // 这样方便枚举相邻格子
main() {
cin >> x;
while (cin >> x >> y >> z) {
x = x << 30 | y;
W(-);
H[x] += z;
W();
cout << a << "\n";
}
}
尽管上面的代码有许多肉眼可见的优化之处,但它仍是赛时最短代码。
赛后代码:
#include<bits/stdc++.h>
using namespace std;map<long,long>H;uint64_t a,x,y,W=2e9;main(long z){for(cin>>z;cin>>x>>y>>z;cout<<a<<"\n")for(H[x+=y*W]+=z;int i:{y=1,-y,W,-W})a+=clamp(H[x]-H[x+i],0l,z)*2-z;}
格式化后:
#include <bits/stdc++.h>
using namespace std;
map<long, long> H;
uint64_t a, x, y, W = 2e9; // uint64_t = unsigned long long
main(long z){
for (cin >> z; cin >> x >> y >> z; cout << a << "\n") // 读入
for (H[x += y * W] += z; int i : {y = 1, -y, W, -W})
// 循环开始前 x += y * W; H[x] += z
// 随后枚举四个方向(1 与 W 类型不同,不能直接写 {1, -1, W, -W})
a += clamp(H[x] - H[x + i], 0l, z) * 2 - z;
// clamp(a, l, r) = max(min(a, r), l)
}
后记
对代码长度的压缩远不只是删除空白字符、使用单字母变量名那么简单,它需要你了解你使用的语言、适时合并语句、精心调整代码逻辑,有时还要求你掌握一门不可读的语言(对于不限制语言的 code golf)。在此欢迎大家来玩 破防人五号 Code Golf。