题解:P14518 APLSPC
EastSnowLotus · · 题解
疑似是爆了目前所有已有代码的标的?
首先这个题要素非常多,我们来逐个处理。
- 这个程序能够输出自己。
- 这个程序在 Python 下和 C++ 下都能够运行
- 这个程序不包含这两个语言的任何关键字
首先 1 是非常经典的问题,LibreOJ #4 Quine 就是这道题目。一般的方法是用一个字符串把外面的整个代码都复制一遍,然后把这个串自己输出出来。
r='r=%r;print r%%r';print r%r
char*s="char*s=%c%s%c;main(){__builtin_printf(s,34,s,34);}";main(){__builtin_printf(s,34,s,34);}
接下来看 2,这个部分需要我们把 cpp 的代码和 py 的代码综合起来。
想要综合起来肯定不简单,我们可以从以下角度入手:
#define可以被 Python 无视,这启发我们 define 很多东西然后把 C++ 的部分和 Python 融合起来1//1在 Python 中只是一个表达式,但是在 C++ 里面就是注释了,这样我们可以在这个后面紧接着放 Python 部分的输出
大概可以得到一个这样的代码:
#define S main(){char*s
S=s="#define S main(){char*s%cS=s=%c%s%c;1//1;input(s%%(10,34,s,34,10,10))%c#define S;__builtin_printf(s,10,34,s,34,10,10);}%cS";1//1;input(s%(10,34,s,34,10,10))
#define S;__builtin_printf(s,10,34,s,34,10,10);}
S
此时在 LOJ 上可以通过,但是注意实际上 Hydro 并不能使用 input,因此必须改为 print(end=....)。另外,我们现在还有一个 char。为了解决这一问题,我们可以利用 define 的特性:在中间加一个 ##。
因为在实际应用中如果遇到 #define func(x) 并且里面有一些只与 x 相关的内容,所以 C++ 给出了 ## 功能,即 x##qwq 在实际调用时会把 qwq 拼接在传入的 x 后面,于是我们只需要把 char 改成 ch##ar 即可以最小代价解决问题。
这个时候数一下你的代码,发现离 250B 十分接近了,但是现在似乎并没有什么很能优化的地方了。
但是,注意到 S=s= 其实可以直接改为 S=,只需要把 Python 部分的输出相应的改成 S 即可,这样我们成功又减少了几个字符,最后字符数量恰好为 250,完美通过。
当然,其实这份代码也许还有继续优化下去的机会,如果有人有思路或者有其他的方法达到更短的长度也可以联系我,我可能也会继续更新这篇题解。