以下用invstr存储5进制的字符串,image二维数组存储图像。
solvemap和fillmap分别处理两种不同的情况。
注意输出格式:样例之间有空行,但最后不能有空行;每两个数字之间有空格,但最后不能有空格,并且每打印12个数字则应换行。
#include<iostream>
#include<string>
#include<cassert>
#include<algorithm>
#include<map>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<set>
using namespace std;
int qsize;
const int maxn = 64 + 5;
int image[maxn][maxn];
set<string>invstr;
string digitToInvStr(int x)
{
string s;
while (x > 0)
{
s.append(1, x % 5 + '0');
x /= 5;
}
reverse(s.begin(), s.end());
return s;
}
int invStrTodigit(const string& s)
{
int sum = 0;
int factor = 1;
for (int i = s.size() - 1; i >= 0; --i)
{
sum += (s[i] - '0') * factor;
factor *= 5;
}
return sum;
}
int isAllsame(int le, int ri, int up, int d)//-1为白,0为有黑有白,1为黑
{
int white = 0, black = 0;
for (int i = le; i < ri; ++i)
{
for (int j = up; j < d; ++j)
{
if (image[i][j] == 1)
++black;
else
++white;
}
}
if (white == 0)
return 1;
if (black == 0)
return -1;
return 0;
}
void solvemap(int le, int ri, int up, int d, string s);
void dep(int le, int rl, int up, int d, string s)
{
if (isAllsame(le, rl, up, d) == 1)
{
invstr.insert(s);
}
else if (isAllsame(le, rl, up, d) == 0)
{
solvemap(le, rl, up, d, s);
}
}
void solvemap(int le, int ri, int up, int d,string s)
{
int midc = (ri + le) / 2, midr = (up + d) / 2;
dep(le, midc, up, midr, "1" + s);
dep(le, midc, midr, d, "2" + s);
dep(midc, ri, up, midr, "3" + s);
dep(midc, ri, midr, d, "4" + s);
}
void fillmap(int le,int ri,int up,int d,string s)
{
if (s.empty())
{
for (int i = le; i < ri; ++i)
{
for (int j = up; j < d; ++j)
{
image[i][j] = 1;
}
}
return;
}
int midc = (ri + le) / 2, midr = (up + d) / 2;
string sub = s.substr(0, s.size() - 1);
char c = s[s.size() - 1];
if (c == '1')
fillmap(le, midc, up, midr, sub);
else if (c == '2')
fillmap(le, midc, midr, d, sub);
else if (c == '3')
fillmap(midc, ri, up, midr, sub);
else if (c == '4')
fillmap(midc, ri, midr, d, sub);
}
int main()
{
//freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
int kase = 1;
while (cin >> qsize && qsize != 0)
{
memset(image, 0, sizeof(maxn));
invstr.clear();
string str;
if (kase != 1)
cout << endl;
cout << "Image " << kase++ << endl;
if (qsize > 0)
{
cin.get();
for (int i = 0; i < qsize; ++i)
{
string tmp;
getline(cin, tmp);
for (int j = 0; j < qsize; ++j)
image[i][j] = tmp[j] - '0';
}
if (isAllsame(0, qsize, 0, qsize)==1)
{
cout << 0 << endl;
invstr.insert("0");
}
else if (isAllsame(0, qsize, 0, qsize) == 0)
{
vector<int>out;
solvemap(0, qsize, 0, qsize, str);
int i = 0;
for (auto &elem:invstr)
{
out.push_back(invStrTodigit(elem));
}
sort(out.begin(), out.end());
for (auto& elem : out)
{
if (i % 12 != 0)
cout << " ";
else if(i != 0)
cout << endl;
cout << elem;
++i;
}
cout << endl;
}
cout << "Total number of black nodes = " << invstr.size() << endl;
}
else
{
int tmp;
qsize *= -1;
while (cin >> tmp && tmp != -1)
{
if (tmp == 0)
{
invstr.insert("");
}
invstr.insert(digitToInvStr(tmp));
}
if (tmp == 0 || !invstr.empty())
{
for (auto& elem : invstr)
{
fillmap(0, qsize, 0, qsize, elem);
}
}
for (int i = 0; i < qsize; ++i)
{
for (int j = 0; j < qsize; ++j)
{
if (image[i][j] == 1)
cout << '*';
else
cout << '.';
}
cout << endl;
}
}
}
}