题解 P2191 【小Z的情书】
Nemlit
2017-11-19 17:52:23
#模拟题
模拟题的代码一般都很长,所以检查起来就很麻烦。这道题我写代码只用了5分钟,可调式却用了30分钟。本题的思路是离线搜索,从四个方向依次搜索,搜到及输出。第二个方向和第四个方向的代码比较麻烦,想的话可能想很久很久都不明白。我的第二个方向错误代码是这样的:
```cpp
for(int i=n;i>0;i--)
for(int j=1;j<=n;j++)
if(b[i][j])
cout<<arr[i][n-j+1];
```
想了很久才想明白搜索的思路。你只要想清楚每个方向的起始值和输出值,其实这道题就很简单了。然后贴代码:
```cpp
#include<bits/stdc++.h>
using namespace std;
bool b[1005][1005]={0};//存透明的板子
int n;
char temp,arr[1005][1005];//存‘情书’
int main(){
cin>>n;
for(int i=1;i<=n;i++)//输入透明的板子,由于b数组初值已经负为0,所以就不用管‘#’的情况了
for(int j=1;j<=n;j++){
cin>>temp;
if(temp=='O')
b[i][j]=1;
}
for(int i=1;i<=n;i++)//输入‘情书’
for(int j=1;j<=n;j++)
cin>>arr[i][j];
for(int i=1;i<=n;i++)//正面读,这一块十分简单,不多做讲解
for(int j=1;j<=n;j++)
if(b[i][j])
cout<<arr[i][j];
for(int i=1;i<=n;i++)//第一次旋转读,观察后可发现样例顺序如下:(4,1)(3,1)(2,1)(1,1)(4,2)……所以i代表纵坐标,从1~n,j则代表横坐标,从n~1
for(int j=n;j>0;j--)
if(b[j][i])
cout<<arr[i][n-j+1];//因为输出值都是用正常数据输出,所以纵坐标应该是n-j+1
for(int i=n;i>0;i--)//同第一次
for(int j=n;j>0;j--)
if(b[i][j])
cout<<arr[n-i+1][n-j+1];
for(int i=n;i>0;i--)//同第二次
for(int j=1;j<=n;j++)
if(b[j][i])
cout<<arr[n-i+1][j];
return 0;
} //2191
```