题解 P1059 【明明的随机数】for-else语句的实现

这题要求去重, 排序, 那么就先暴力 $n^2$ 去重走起.

因为算法没啥好讲的所以本篇讲的是一个语法技巧

这里我为了少用一个flag变量所以使用了一个for循环全部结束后运行的方法(相当于python中的$for…else$语句)

我们知道for循环有三个子表达式, 定义为 $for(expr1;expr2;expr3)$ , 其中 $expr1$ 表示初始化语句, 在进入for循环时调用, $expr2$ 表示循环控制语句, 在 $expr2$ 值为 $true$ 是才会进行一次循环, $expr3$ 是递增语句.

我们分析 $for…else$ 语句会发现, $else$ 子句运行条件是 $for$ 子句完全运行完毕后, 即当 $expr2$ 不成立的时候就会运行 $else$ 子句. 那么我们就会想到短路运算, 只有 $op1$ 不成立才会运行 $op2$, 即逻辑或运算符. 那么结构为: for (expr1; expr2 || expr-else; expr3).

但是我们发现如果expr-else的值是true的话就会继续循环, 我们要保证expr-else的值一定是false, 所以使用逗号表达式, 这个表达式从左到右运算并返回最后一个子句的值, 那么就可以写成如下形式: for (expr1; expr2 || (expr-else, false); expr3), 这就相当于 for (expr1; expr2; expr3) { ... } else { expr-else }

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <algorithm>

using namespace std;

int main() {
short n, t, c = 0;
cin >> n;
short *num = new short[n];
while (n--) {
cin >> t;
for (int i = 0; i < c || (num[c++] = t, false); ++i) if (num[i] == t) break;
}
cout << c << endl;
sort(num, num + c);
for (int i = 0; i < c; ++i) cout << num[i] << " ";
return 0;
}