Codeforces Round #470 Div. 2题解
题意:给定一个$R\times C$的草坪,草坪上有一些羊和一些狼,你可以在羊的周围放一些狗,有狗的地方狼就过不去了,问是否存在一种方案使得所有的羊都能不被吃掉,并输出任意一组解。
题解:随便输出一组解的话,我们可以贪心地思考,把每一块空地都放一只狗,然后以每一只狼为起点进行一遍DFS,如果能碰到羊就无解,如果到最后都没有羊被吃掉,那么就输出方案。
#include<cstdio> #include<cstring> #include<cstdlib> using namespace std; char a[510][510]; bool vis[510][510]; int r,c; const int dx[]={-1,1,0,0},dy[]={0,0,1,-1}; void dfs(int x,int y) { if(a[x][y]=='S') { puts("No"); exit(0); } int xx,yy; for(int i=0;i<4;i++) { xx=x+dx[i],yy=y+dy[i]; if(xx>=0&&yy>=0&&xx<r&&yy<c&&a[xx][yy]!='D') { if(!vis[xx][yy]) { vis[xx][yy]=1; dfs(xx,yy); } } } } int main() { scanf("%d%d",&r,&c); for(int i=0;i<r;i++) scanf("%s",a[i]); for(int i=0;i<r;i++) for(int j=0;j<c;j++) if(a[i][j]=='.') a[i][j]='D'; for(int i=0;i<r;i++) for(int j=0;j<c;j++) if(a[i][j]=='W') dfs(i,j); puts("Yes"); for(int i=0;i<r;i++) printf("%s\n",a[i]); return 0; }
这么水的题竟然写了接近50行qwq。。。
题意:两个人玩游戏,先指定一个$X_0$,第$i$轮的时候他会选择一个满足$p\le X_i$的质数,然后找到一个最小的数满足$X_{i+1}>X_i,X_{i+1}\mid p$,如此进行若干轮。现在给定你$X_2$,你要求出最小的$X_0$。
题解:令$P(N)$为$N$的最大质因数,显然我们可以通过选择$P(N)$作为每次操作的质数获得区间$[N-P(N)+1,N]$中的任意数,并且我们不能从其他任何数获得$N$。通过分解$X_2$,我们可以找到$X_1$的区间,通过分解$X_1$区间中的所有数,我们可以找到$X_0$的区间,答案是$X_1$区间交集的最小元素。
题意:有$N$堆雪,每堆雪都有一定体积,第$i$天每堆雪的体积都会缩小$T[i]$,求$1$到$N$天融化的雪的体积。
题解:由于$T[i]$是固定的,我们只需要确定每堆雪融化完的时间即可。对每堆雪的融化量做一个前缀和,然后就可以维护每天化了多少雪了。对于每堆雪的融化完成时间,直接在做前缀和的过程中就能处理完。
题意:给定两组数,求这两组数两两异或后连接起来字典序最小的一组。
题解:我们贪心的解密每一对数,考虑要维护一些数的异或和,我们直接上Trie树把数的每一位分解,记录个数,然后在Trie树上寻找最优解即可。
题意:给两个只有$A,B,C$的字符串$S$和$T$,有$Q$次询问,每次询问能否将$S$的一段区间$[a_i,b_i]$变换为$T$的一段区间$[c_i,d_i]$。
变换方式如下:
\begin{equation*}
\begin{aligned}
A&\rightarrow BC\\
B&\rightarrow AC\\
C&\rightarrow AB\\
AAA&\rightarrow\varnothing
\end{aligned}
\end{equation*}
题解:
根据所给条件,我们对字符串进行一些变换,容易发现一些单个字符变换的规律:
\begin{equation*}
\begin{aligned}
&B\rightarrow AC\rightarrow AAB\rightarrow\mathbf{AAA}C\rightarrow C\\
&C\rightarrow AB\rightarrow AAC\rightarrow\mathbf{AAA}B\rightarrow B\\
&B\rightarrow AC\rightarrow AAB\rightarrow\mathbf{AAA}C\rightarrow\mathbf{AAA}AB\rightarrow AB\\
&C\rightarrow AB\rightarrow AAC\rightarrow\mathbf{AAA}B\rightarrow\mathbf{AAA}AC\rightarrow AC\\
&A\rightarrow BC\rightarrow BAB\rightarrow BAAC\rightarrow B\mathbf{AAA}B\rightarrow BB\\
\end{aligned}
\end{equation*}
由上述一些规律我们还容易得到:
\begin{equation*}
\begin{aligned}
&B\rightarrow AC\rightarrow AB\rightarrow BBB\\
&AAB\rightarrow \mathbf{AAA}C\rightarrow C\rightarrow B\\
&AB\rightarrow ACB\rightarrow ABB\\
\end{aligned}
\end{equation*}
综上所述,我们得到以下一些结论:
\begin{align}
&B\Leftrightarrow C\\
&B每次可以增加偶数个\\
&在B之前出现的A都可以删除\\
\end{align}
于是我们得到了原字符串和目标字符串之间的关系:
- 目标字符串中的$B$与$C$的数量和必须大于等于原字符串中的$B$与$C$的数量和
- 目标字符串中的$B$与$C$的数量和的奇偶性必须与原字符串中的$B$与$C$的数量和相同
最后,如果原字符串中的$B$和$C$的数量与目标字符串中的$B$和$C$的数量相等,那么没有操作$1$和操作$2$,只能将后面的$A$减少$3n,n\in N$个。由于所有操作都无法增加原字符串末尾的$A$的个数,如果原字符串末尾$A$的个数少于目标字符串就无解,否则对3取个模然后与目标字符串末尾$A$的个数对3取模的结果判一下是否相等就行了。
至于怎么维护两个字符串中$B$和$C$的数量,直接上前缀和预处理一下就行了。