题解:P14518 [NFLSPC #8] APLSPC

· · 题解

神仙题目

思路

前置:#define 是 C++ 的文本宏替换指令,详见这里

思路 1

下面的代码可以区分 C++ 和 Python 的代码。

#isndef __cplusplus
'''
#endif

#include<bits/stdc++.h>
int main(){
    cout<<"C++ 代码";
}

#isndef __cplusplus
'''
print("Python 代码")
#endif

:::info[解释]

对于 C++,下面的代码高亮的部分是 C++ 会执行的部分(并不严谨)。

#isndef __cplusplus
'''
#endif

#include<bits/stdc++.h>
int main(){
    cout<<"C++ 代码";
}

#isndef __cplusplus
'''
print("Python 代码")
#endif

对 C++ 而言,这份代码:

对于 Python,下面同样一份代码高亮的部分是 Python 会执行的部分。可能从渲染就能看出来

#isndef __cplusplus
'''
#endif

#include<bits/stdc++.h>
int main(){
    cout<<"C++ 代码";
}

#isndef __cplusplus
'''
print("Python 代码")
#endif

对 Python 而言,这份代码:

于是可以在这份代码的基础上对 C++ 和 Python 分别写一个 Quine,但是代码长度很长,这里不展示代码。

思路 2

于是你在上一个代码的基础上进行优化,你会发现不需要那么复杂的判断,只需要一行 #define 就能隔开。

:::info[解释] C++ 会执行 #define 命令,而 Python 会把 # 后面的所有内容当成注释。

因此可以使用 #define 来隔开 C++ 和 Python 的代码。 :::

然后你又希望 C++ 和 Python 可以共享定义字符串的代码(因为可以不用写两遍),于是按照这个想法,你可以写出下面的东西:

#include<cstdio>
#define A main(){char*b
A="code";1//1;print(A)
#define A;printf(b);}
A

得益于宏,这份代码在 C++ 约等于下面的代码:

#include<cstdio>
main(){char*b="code";1;printf(b);}

是的,1; 是可以编译通过的,顶多只会给你来一个警告。

又因为 #define 的开头是一个 #,这份代码在 Python 又约等于下面的代码:

A="code";1//1;print(A)
A

1//1; 在 Python 下会是一个语句(表示 \lfloor\frac{1}{1}\rfloor),没有作用,所以后面被 C++ 用 // 当成注释的部分会被 Python 执行。

然后只需要把 code 替换成代码即可。结果巧合的是 C++ 和 Python 都支持使用 %c(输出单个字符)和 %s(输出一个字符串),于是输出部分也简单了。

注意在 Python 会因为 print 而多一个换行。于是使用 print(...,end='') 来避免换行。

大概长这样:

#include<cstdio>
#define A main(){char*b
A="#include<cstdio>%c#define A main(){char*b%cA=%c%s%c;1//1;print(A%%(10,10,34,A,34,10,10),end='')%c#define A;printf(b,10,10,34,b,34,10,10);}%cA";1//1;print(A%(10,10,34,A,34,10,10),end='')
#define A;printf(b,10,10,34,b,34,10,10);}
A

于是它可以在两个语言下都输出自己了。

提交,得到 65pts。原因是因为有 char 关键字。

又又又得益于 #define,直接在 char 中间加上 ## 即可。在这个情况下,ch##archar 是等效的。修正后即可拿下 93pts。

然后你又发现有个东西叫做 __builtin_printf,不用头文件,省事。直接拿这个替代 printf,拿下 98pts,比答案多 6 bytes。

此时你极其绝望,试图肘击出题人。

但是 end 后面可能不止跟一个字符,可能是一个字符串。你极其天才地想到把 A%(10,10,34,A,34,10,10) 丢到 end 里,刚好优化 6 bytes。

250 bytes,AC!

代码

C++ 渲染

#define A main(){ch##ar*b
A="#define A main(){ch##ar*b%cA=%c%s%c;1//1;print(end=A%%(10,34,A,34,10,10))%c#define A;__builtin_printf(b,10,34,b,34,10,10);}%cA";1//1;print(end=A%(10,34,A,34,10,10))
#define A;__builtin_printf(b,10,34,b,34,10,10);}
A

Python 渲染

#define A main(){ch##ar*b
A="#define A main(){ch##ar*b%cA=%c%s%c;1//1;print(end=A%%(10,34,A,34,10,10))%c#define A;__builtin_printf(b,10,34,b,34,10,10);}%cA";1//1;print(end=A%(10,34,A,34,10,10))
#define A;__builtin_printf(b,10,34,b,34,10,10);}
A

后记

出题人我【数据删除】