写出下面题目的程序代码(C++) 并且输入输出都截个图 谢谢~

Divide et unita
Time Limit:5S Memory Limit:5000K
Total Submit:30 Accepted:5 Special Judged
Description
A polyomino is a two-dimensional figure formed from several squares with adjacent sides so that all the squares of polyomino can be visited by the rook moving each turn from one square belonging to the figure to its vertical or horizontal neighbour, also belonging to the figure.

On an infinite squared paper sheet N^2 squares are marked (2<=N<=5) that forms a polyomino P. You should write a program that divides this polyomino into two other polyominos, A and B, wherefrom using rotations and parallel translations (mirror reflection is not allowed), it is possible to assemble a square N*N. Only one of the possible solutions should be found.
Input
The input file will contain an image of a part of the sheet that contains the polyomino P, represented by the characters '.' (dot) denoting empty spaces and '*' (asterisk) denoting squares that belong to the figure (because it is impossible to put infinite squared sheet in a file, the input file describes only part of it; all the omitted squares are considered empty). There will be no other characters in the lines of the input file. The input file will not contain lines that are longer than 100 characters and there will be no more than 100 lines. There will be always at least one solution for the given input file.
Output
Echo the image of the given part of sheet with polyomino into the output file replacing each asterisk with characters 'A' or 'B' in accordance with which of polyominos (parts), A or B, this square belongs to. The output file should contain the same lines with the same order except for the above described changes.
Sample Input
..
......
....*.
..*.*
..***
..****
..*..*
..****
.......
Sample Output
..
......
....B.
..B.B
..BBB
..AABA
..A..A
..AAAA
.......
Hint
The input maybe as large as 100*100
Source
对 是ACM的题目 没办法 老师要求我们做啊
牛人帮帮忙啊 !!!!

//记的以前学校时写过,好像是POJ的题目。源代码还在电脑上留着,仅供参考

#include <iostream>
#include <cmath>

using namespace std;

const int MAXN = 30;
const int MAXM = 101;
const int MAXP = 16;
const int MAXT = 6;

struct Tpoint {
int x, y;
};

Tpoint u[MAXN],v[MAXN],w[MAXN],p[MAXN];
int step[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
int mark[MAXM][MAXM], map[MAXP][MAXP], board[MAXT][MAXT];
int num, cnt, ver, size;
bool cover[MAXM][MAXM];
char line[MAXM][MAXM];

//判断B集合中的连通性
inline int connect(int x, int y)
{
int front = 0, rear = 1;
w[rear].x = x; w[rear].y = y; board[x][y] = 0;
while(front < rear) {
front ++;
for(int i = 0; i < 4; i ++) {
int tx = w[front].x + step[i][0];
int ty = w[front].y + step[i][1];
if(tx >= 0 && tx < size && ty >= 0 && ty < size && board[tx][ty]) {
board[tx][ty] = 0;
rear++;
w[rear].x = tx;
w[rear].y = ty;
}
}
}
return rear;
}

//通过平移判断两个集合是否刚好构成N*N的图形
inline bool match(int minx2, int miny2, int maxx2, int maxy2, int maxx1, int maxy1)
{
for(int i = maxx2 - size + 1; i < minx2 + size - maxx1; i ++) {
for(int j = maxy2 - size + 1; j < miny2 + size - maxy1; j ++) {
bool flag = true;
for(int k = 0; k < num; k ++) {
if(map[v[k].x+i][v[k].y+j]) {
flag = false;
break;
}
}
if(flag) return true; //集合A和集合B刚好能组成size*size的正方形,返回true;
}
}
return false;
}

inline bool ok(int minx2, int miny2, int maxx2, int maxy2) //参数传递集合A的边界
{
int i, j, minx1, miny1, maxx1, maxy1;
minx1 = miny1 = 200; maxx1 = maxy1 = 0;
for(i = 0; i < ver; i ++) {
if(! cover[p[i].x][p[i].y]) { //标记集合B的边界
if(minx1 > p[i].x) minx1 = p[i].x;
if(miny1 > p[i].y) miny1 = p[i].y;
if(maxx1 < p[i].x) maxx1 = p[i].x;
if(maxy1 < p[i].y) maxy1 = p[i].y;
}
}
num = 0;
memset(map, 0, sizeof(map));
for(i = 0; i < ver; i ++) {
if(! cover[p[i].x][p[i].y]) {
if((p[i].x - minx1 >= size) || (p[i].y - miny1 >= size))
return false;

//集合B的边界超过size*size,返回false
v[num].x = p[i].x - minx1; //将集合B往左上角移
v[num].y = p[i].y - miny1;
num ++;
}else {
map[p[i].x - minx2 + 5][p[i].y - miny2 + 5]=1; //将集合A往右下角移
}
}
memset(board, 0, sizeof(board));
for(i = 0; i < num; i ++)
board[v[i].x][v[i].y] = 1;
if(connect(v[0].x,v[0].y)<num) return false; //集合B不连通返回false
maxx2 = maxx2 - minx2 + 5; maxy2 = maxy2 - miny2 + 5;
minx2 = miny2 = 5;
maxx1 = maxx1 - minx1; maxy1 = maxy1 - miny1;
minx1 = miny1 = 0;
for(i = 0; i < 4; i ++) { //4次旋转
if(match(minx2, miny2, maxx2, maxy2, maxx1, maxy1))

//集合A与B刚好能够组成size*size的正方形,返回true
return true;
minx1 = miny1 = INT_MAX; maxx1 = maxy1 = INT_MIN;
for(j = 0; j < num; j ++) {
int temp = v[j].y;
v[j].y = size - v[j].x - 1;
v[j].x = temp;
if(minx1 > v[j].x) minx1 = v[j].x;
if(miny1 > v[j].y) miny1 = v[j].y;
if(maxx1 < v[j].x) maxx1 = v[j].x;
if(maxy1 < v[j].y) maxy1 = v[j].y;
}
for(j = 0; j < num; j ++) {
v[j].x -= minx1; v[j].y -= miny1; //将集合B往左上角移
}
maxx1 -= minx1;maxy1 -= miny1;
}
return false;
}

inline bool dfs(int minx, int miny, int maxx, int maxy, int m, int k)
{
if(k > m) return false;
if(dfs(minx, miny, maxx, maxy, m, k + 1)) return true; //k点不属于集合A
if(abs(u[k].x - minx) >= size || abs(u[k].y - miny) >= size ||
abs(u[k].x - maxx) >= size || abs(u[k].y - maxy) >= size)

//若集合A超过边界size,则返回false
return false;
int i, tx, ty;
for(i = 0; i < 4; i ++) {
tx = u[k].x + step[i][0];
ty = u[k].y + step[i][1];
if(line[tx][ty] == '*' && ! mark[tx][ty]) { //可扩展点进行标记
m ++;
u[m].x = tx;
u[m].y = ty;
mark[tx][ty] = k;
}
}
cover[u[k].x][u[k].y] = true;
if(ok(__min(minx, u[k].x), __min(miny, u[k].y), __max(maxx, u[k].x), __max(maxy, u[k].y)))

//若刚好能组成size*size的正方形,则返回true
return true;
if(dfs(__min(minx, u[k].x), __min(miny, u[k].y), __max(maxx, u[k].x), __max(maxy,u[k].y), m, k + 1))//继续搜索集合A,若成功返回true
return true;
cover[u[k].x][u[k].y] = false;
for(i = 0; i < 4; i ++) {
tx = u[k].x + step[i][0];
ty = u[k].y + step[i][1];
if(mark[tx][ty] == k) mark[tx][ty] = 0; //消除标记
}
return false;
}

int main()
{
cnt = 0;
while(gets(line[cnt++])); //读入数据
ver = 0;
for(int i = 0; i < cnt; i ++)
for(int j = 0; line[i][j]; j ++)
if(line[i][j] == '*') {
p[ver].x = i; p[ver].y = j; ver ++;
}
size = (int)sqrt((double)ver); //正方形的边长为size
memset(cover, false, sizeof(cover));
memset(mark, 0, sizeof(mark));
u[1].x = p[0].x; u[1].y = p[0].y;
mark[u[1].x][u[1].y] = -1;
dfs(u[1].x, u[1].y, u[1].x, u[1].y, 1, 1); //搜索集合A的可能情况
for(i = 0; i < cnt; i ++) {
for(int j = 0; line[i][j]; j ++) {
if(line[i][j]=='*') {
if(cover[i][j]) printf("A");
else printf("B");
}else printf(".");
}
printf("\n");
}
return(0);
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-09-05
ACM的题吧?
第2个回答  2009-09-05
中间的一个点是半个字符
你把它单独拿出来看看
不过不知道支不支持半个字符的打印
相似回答