题目大意:中文
注释代码:
/*
* Problem ID : NPOJ 1064 原原的密信
* Author : Lirx.t.Una
* Language : C++
* Run Time : 7
* Run Memory : 1692
*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
#include <cctype>
//密信的最大宽度
#define MAXN 21
using namespace std;
double xo, yo;//密信的中点坐标
struct Point {//假设密信是一个第一象限的直角坐标系
//左下角为(1, 1)
int x, y;
Point(void) {}
Point( int xx, int yy ) : x(xx), y(yy) {}
bool//对洞处的所有点按照从上到下从左到右的顺序进行排序
operator<(const Point &oth)
const {
if ( y != oth.y ) return y > oth.y;
else return x < oth.x;
}
void
trans(void) {//对洞处的点进行直角旋转(顺时针)
//旋转可以看成是相对中点旋转90度,因此求相对中点的向量(dx, dy)
//然后做变换(dy, -dx)就得到了变换后的相对中点的向量
//最后(x + dy, y - dx)就是最终变换后的结果
//注意!:中点的值可能是带.5的小数,注意类型转换
double dx, dy;
dx = (double)y - yo;
dy = xo - (double)x;
x = (int)( xo + dx );
y = (int)( yo + dy );
}
};
char m[MAXN][MAXN];//matrix,密信
char fmt[5];//格式化字符串
int
main() {
int n, l;//密信的宽度和密码的长度
int x, y;//计数变量,指示坐标
int iscn;
char ctmp;//临时字符变量
iscn = 0;
while ( ~scanf("%d%d", &n, &l) ) {
vector<Point> v;//存放所有洞处的点
vector<Point>::iterator it;
//计算密信中点坐标
xo = (double)n / 2.0 + 0.5;
yo = xo;
for ( y = n; y > 0; y-- )//输入密信信息
for ( x = 1; x <= n; x++ ) {
scanf("%s", fmt);
m[x][y] = *fmt;
}
for ( y = n; y > 0; y-- )//将所有洞处的点存入v中
for ( x = 1; x <= n; x++ ) {
scanf("%s", fmt);
if ( 'O' == *fmt )
v.push_back( Point( x, y ) );
}
//由于初始化时点就是按照从上到下从左到右的顺序的,因此不需要排序
printf("Case #%d: ", ++iscn);
while ( true ) {
for ( it = v.begin(); it != v.end() && l; it++, l-- ) {//当密码还没输完时
//继续输出
//注意还有','和'.'两种字符
if ( ',' == ( ctmp = m[ it->x ][ it->y ] ) || '.' == ctmp )
putchar(ctmp);
else
putchar(tolower(ctmp));//注意将大写改成小写
}
if ( !l ) break;//如果密码输完则推出
v.erase(v.begin());//否则就先删去第一个点
for ( it = v.begin(); it != v.end(); it++ ) it->trans();//然后再对剩余点做变换
sort(v.begin(), v.end());//变换之后按照从上到下从左到右的顺序进行排序
}
putchar('\n');
}
return 0;
}
无注释代码:
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
#include <cctype>
#define MAXN 21
using namespace std;
double xo, yo;
struct Point {
int x, y;
Point(void) {}
Point( int xx, int yy ) : x(xx), y(yy) {}
bool
operator<(const Point &oth)
const {
if ( y != oth.y ) return y > oth.y;
else return x < oth.x;
}
void
trans(void) {
double dx, dy;
dx = (double)y - yo;
dy = xo - (double)x;
x = (int)( xo + dx );
y = (int)( yo + dy );
}
};
char m[MAXN][MAXN];
char fmt[5];
int
main() {
int n, l;
int x, y;
int iscn;
char ctmp;
iscn = 0;
while ( ~scanf("%d%d", &n, &l) ) {
vector<Point> v;
vector<Point>::iterator it;
xo = (double)n / 2.0 + 0.5;
yo = xo;
for ( y = n; y > 0; y-- )
for ( x = 1; x <= n; x++ ) {
scanf("%s", fmt);
m[x][y] = *fmt;
}
for ( y = n; y > 0; y-- )
for ( x = 1; x <= n; x++ ) {
scanf("%s", fmt);
if ( 'O' == *fmt )
v.push_back( Point( x, y ) );
}
printf("Case #%d: ", ++iscn);
while ( true ) {
for ( it = v.begin(); it != v.end() && l; it++, l-- ) {
if ( ',' == ( ctmp = m[ it->x ][ it->y ] ) || '.' == ctmp )
putchar(ctmp);
else
putchar(tolower(ctmp));
}
if ( !l ) break;
v.erase(v.begin());
for ( it = v.begin(); it != v.end(); it++ ) it->trans();
sort(v.begin(), v.end());
}
putchar('\n');
}
return 0;
}