这是我第一次在ACM的题目中用OO的思想写的程序,看到标程,竟不谋而合,结构是类似的。对正方形这个类分析,将会使问题变得简单,我觉得OO的分析和设计挺关键的,其实我一开始也没设计好,原先准备把7个bool函数当成类的成员方法,其实这个设计是不好的,有点过了。其实应该是把旋转90度和轴对称这两个方法作为类的成员方法,这样main中调用就方便自如了。
最后,我觉得搞ACM,不仅是把题目A掉,同时也应注意程序的结构设计,因为”程序是给人看的“。
// #define ONLINE_JUDGE #define MY_DEBUG #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <vector> #include <string> #include <algorithm> #include <cstdio> #include <cassert> using namespace std; class Square { private: typedef vector<char> vChar; typedef vector<vChar> vvChar; vvChar data; unsigned n; public: // 用边长来构造 Square (unsigned _n) : n(_n) {} Square rotateClockwise90() { Square tmp(n); for (unsigned int i = 0; i < tmp.n; ++i) { Square::vChar vcTmp; for (unsigned int j = 0; j < tmp.n; ++j){ vcTmp.push_back(this->data[n - 1 - j][i]); } tmp.data.push_back(vcTmp); } return tmp; } Square rotateClockwise180() { return this->rotateClockwise90().rotateClockwise90(); } Square rotateClockwise270() { return this->rotateClockwise180().rotateClockwise90(); } Square reflecteHorizontal() { Square tmp(n); for (unsigned int i = 0; i < tmp.n; ++i) { Square::vChar vcTmp; for (unsigned int j = 0; j < tmp.n; ++j){ vcTmp.push_back(this->data[i][n - j - 1]); } tmp.data.push_back(vcTmp); } return tmp; } bool operator==(const Square &other) const { if (this->n != other.n) { return false; } for (unsigned i = 0; i < n; ++i) { for (unsigned j = 0; j < n; ++j) { if (this->data[i][j] != other.data[i][j]) { return false; } } } return true; } friend istream & operator>>(istream& is, Square &s) { for (unsigned int i = 0; i < s.n; ++i) { Square::vChar vcTmp; for (unsigned int j = 0; j < s.n; ++j){ char cTmp; cin >> cTmp; vcTmp.push_back(cTmp); } s.data.push_back(vcTmp); } return is; } friend ostream & operator<<(ostream& os, const Square &s) { for (unsigned int i = 0; i < s.n; ++i) { if (i >= 1) { cout << endl; } for (unsigned int j = 0; j < s.n; ++j){ if (j >= 1) { cout << " "; } cout << s.data[i][j]; } } return os; } }; int main() { #ifndef ONLINE_JUDGE freopen("transform.in", "r", stdin); freopen("transform.out", "w", stdout); #endif unsigned sideLen; cin >> sideLen; Square sa(sideLen); Square sb(sideLen); cin >> sa >> sb; #ifndef MY_DEBUG cout << "sa=\n" << sa << "\n" << endl; cout << "sb=\n" << sb << "\n" << endl; assert(sa.rotateClockwise270() == sa.rotateClockwise90().rotateClockwise90().rotateClockwise90()); #endif if (sa.rotateClockwise90() == sb) { cout << "1" << endl; return 0; } if (sa.rotateClockwise180() == sb) { cout << "2" << endl; return 0; } if (sa.rotateClockwise270() == sb) { cout << "3" << endl; return 0; } if (sa.reflecteHorizontal() == sb) { cout << "4" << endl; return 0; } Square saRe(sa.reflecteHorizontal()); if (saRe.rotateClockwise90() == sb || saRe.rotateClockwise180() == sb || saRe.rotateClockwise270() == sb) { cout << "5" << endl; return 0; } if (sa == sb) { cout << "6" << endl; return 0; } cout << "7" << endl; return 0; }
附:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define MAXN 10 typedef struct Board Board; struct Board { int n; char b[MAXN][MAXN]; }; /* rotate 90 degree clockwise: [r, c] -> [c, n+1 - r] */ Board rotate(Board b) { Board nb; int r, c; nb = b; for(r=0; r<b.n; r++) for(c=0; c<b.n; c++) nb.b[c][b.n+1 - r] = b.b[r][c]; return nb; } /* reflect board horizontally: [r, c] -> [r, n-1 -c] */ Board reflect(Board b) { Board nb; int r, c; nb = b; for(r=0; r<b.n; r++) for(c=0; c<b.n; c++) nb.b[r][b.n-1 - c] = b.b[r][c]; return nb; } /* return non-zero if and only if boards are equal */ int eqboard(Board b, Board bb) { int r, c; if(b.n != bb.n) return 0; for(r=0; r<b.n; r++) for(c=0; c<b.n; c++) if(b.b[r][c] != bb.b[r][c]) return 0; return 1; } Board rdboard(FILE *fin, int n) { Board b; int r, c; b.n = n; for(r=0; r<n; r++) { for(c=0; c<n; c++) b.b[r][c] = getc(fin); assert(getc(fin) == '\n'); } return b; } void main(void) { FILE *fin, *fout; Board b, nb; int n, change; fin = fopen("transform.in", "r"); fout = fopen("transform.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d\n", &n); b = rdboard(fin, n); nb = rdboard(fin, n); if(eqboard(nb, rotate(b))) change = 1; else if(eqboard(nb, rotate(rotate(b)))) change = 2; else if(eqboard(nb, rotate(rotate(rotate(b))))) change = 3; else if(eqboard(nb, reflect(b))) change = 4; else if(eqboard(nb, rotate(reflect(b))) || eqboard(nb, rotate(rotate(reflect(b)))) || eqboard(nb, rotate(rotate(rotate(reflect(b)))))) change = 5; else if(eqboard(nb, b)) change = 6; else change = 7; fprintf(fout, "%d\n", change); exit(0); }
A square pattern of size N x N (1 <= N <= 10) black and white square tiles is transformed into another square pattern. Write a program that will recognize the minimum transformation that has been applied to the original pattern given the following list of possible transformations:
In the case that more than one transform could have been used, choose the one with the minimum number above.
Line 1: | A single integer, N |
Line 2..N+1: | N lines of N characters (each either `@' or `-'); this is the square before transformation |
Line N+2..2*N+1: | N lines of N characters (each either `@' or `-'); this is the square after transformation |
3 @-@ --- @@- @-@ @-- --@
A single line containing the the number from 1 through 7 (described above) that categorizes the transformation required to change from the `before' representation to the `after' representation.
1