题解 P1320 【压缩技术(续集版)】
RedContritio · · 题解
题解区里面一大群人都自诩巧妙,简直是 XXXX,XXXX 。
既然姊妹题目 P1319 压缩技术 能够不存储直接输出,显然这个也应该可以(雾)。
我们可以发现,在第一行读入之前,无法获得 N ,因此,我们可以创建一个数组存储压缩码的结果,而将输入的字符表边读入边处理。
CPP 代码如下(解释见注释)
#include <cstdio>
int d[40020],i=1; // d 记录压缩码(显然恒小于等于 40002 ) , i 用来记录存储的位置
char c; // 临时存储字符
int main()
{
for(;scanf("%c",&c)&&c>0x2F;) // 先读入第一行,不断读入,直到 c 不是 ‘0’(0x30) 和 ‘1’ (0x31) 为止。
i+=!(i&1^(c-0x30)),d[i]++, d[0]++; // 空格以前为祖传神秘代码,解释放到最后;空格以后表示 N 的值自加
// 至此,d[0] 为 N 的值
for(;~scanf("%c",&c);)if( c>0x2F)i+=!(i&1^(c-0x30)),d[i]++; // 不断读入,如果每次内容是 ‘0’ 或 ‘1’ 则 执行祖传语句
for(int j=0;j<=i;j++)printf("%d ",d[j]); // 输出存储好的压缩码
}
现在解释 i+=!(i&1^(c-0x30)),d[i]++;
首先计算 (c-0x30) , 很显然,当 c 为 ‘0’ 时,值为 0 , 当 c 为 ‘1’ 时,值为 1 ;
然后计算 i&1 , 当 i 为奇数时,值为 1 , 否则值为 0 ;
然后计算 (i&1^(c-0x30)) : 当 i 为奇数且 c 为 ‘0’ 时,或 i 为偶数且 c 为 ‘1’时,值为1;否则值为 0 。 (表示 c 是否应该计算到 i 的位置上)
接下来计算 !(i&1^(c-0x30)) , 如果 c 应该被计算到 d[i] 上 ,值为 0 ,否则为 1 。
接下来处理 i+=!(i&1^(c-0x30)) , 如果 c 应该被计算到 d[i] 上,i 不变,否则 i ++ 。
最后就是 i+=!(i&1^(c-0x30)),d[i]++ ,先设置好 i 的位置,然后执行 d[i] ++ 。