題意
給一張圖的兩種表示方法,讓你互相轉化。然後輸出,題意太長,就不翻譯了。
解題思路
圖轉樹: 利用遞歸的寫法很容易想出遞歸的方案,就是先遞歸整張地圖,可以將左上角加長度的一半作爲參數遞歸。這樣可以在遞歸的時候將整張圖分成四塊分別遞歸。當然我的實現方法有點冗餘,沒有用數據結構優化。
樹轉圖:這個比較容易寫,只要將給的數字從十進制轉化爲5進制,一直遞歸然後到最後當數爲0的時候就到了葉子節點,也就是可以畫圖的時候了。
槽點:這題的輸出格式比較是最後一個測試例後面就不用換行, 還有看lrj紫書中說數據都是2的整數次冪,但是注意1也是2的整數冪(/≧▽≦)/。
直接上代碼,不過真的冗餘,寫完我自己都驚呆了 0.0
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <math.h>
#include <queue>
#include <string>
#include <sstream>
#include <vector>
#include <string.h>
using namespace std;
const int maxn = 70;
const int INF = 111;
string s[maxn];
int n;
int cnt = 0;
vector<int> ans;
void init()
{
for (int i = 0; i < maxn; i++)
s[i].resize(maxn);
for (int i = 0; i < maxn; i++)
for (int j = 0; j < maxn; j++)
s[i][j] = '.';
ans.clear();
cnt = 0;
}
//sx sy 遞歸區域的左上角座標 , len: 遞歸區域的邊長的一半(正方形)
void buildTree(int sx, int sy, int len, int val, int base)
{
bool flag = false;
bool flag1 = false;
for (int i = sx; i < sx + len*2; i++)
for (int j = sy; j < sy + len*2; j++)
{
if (s[j][i] == '1')
{
flag = true;
}
if (s[j][i] == '0')
flag1 = true;
}
if (flag && !flag1)
{
ans.push_back(val);
cnt++;
return;
}else if(!flag && flag1)
{
return;
}
flag = false;
flag1 = false;
for (int i = sx; i < sx + len; i++)//左上角 sx, sy
for (int j = sy; j < sy + len; j++)
{
if (s[j][i] == '1')
{
flag = true;
}
if (s[j][i] == '0')
flag1 = true;
}
if (flag)
{
if(flag1)
buildTree(sx, sy, len / 2, val + 1*base, base*5);
else ans.push_back(val + 1 * base),cnt++;
}
flag = false;
flag1 = false;
for (int i = sx + len; i < sx + len * 2; i++)//二號位置 sx+len,sy
for (int j = sy; j < sy + len; j++)
{
if (s[j][i] == '1')
{
flag = true;
}
if (s[j][i] == '0')
flag1 = true;
}
if (flag)
{
if (flag1)
buildTree(sx + len, sy, len / 2, val + base * 2, base * 5);
else ans.push_back(val + base * 2),cnt++;
}
flag = false;
flag1 = false;
for (int i = sx; i < sx + len; i++)//三號位置 sx, sy+len
for (int j = sy + len; j < sy + len * 2; j++)
{
if (s[j][i] == '1')
{
flag = true;
}
if (s[j][i] == '0')
flag1 = true;
}
if (flag)
{
if (flag1)
buildTree(sx, sy + len, len / 2, val + base * 3, base * 5);
else ans.push_back(val + base * 3),cnt++;
}
flag = false;
flag1 = false;
for (int i = sx + len; i < sx + len * 2; i++)//四號位置 sx + len, sy+len
for (int j = sy + len; j < sy + len * 2; j++)
{
if (s[j][i] == '1')
{
flag = true;
}
if (s[j][i] == '0')
flag1 = true;
}
if (flag)
{
if (flag1)
buildTree(sx + len, sy + len, len / 2, val + base * 4, base * 5);
else ans.push_back(val + base * 4),cnt++;
}
}
void draw(int num, int sx, int sy, int len)
{
int dir = num % 5;
if (dir == 0)
{
for (int i = sy; i < sy + len*2; i++)
for (int j = sx; j < sx + len*2; j++)
s[i][j] = '*';
return;
}
if (dir == 1)
{
if (num / 5 == 0)
{
for (int i = sy; i < sy + len; i++)
for (int j = sx; j < sx + len; j++)
s[i][j] = '*';
}
else draw(num/5,sx, sy, len/2);
}
if (dir == 2)
{
if (num / 5 == 0)
{
for (int i = sy; i < sy + len; i++)
for (int j = sx + len; j < sx + len * 2; j++)
s[i][j] = '*';
}
else draw(num / 5, sx+len, sy, len / 2);
}
if (dir == 3)
{
if (num / 5 == 0)
{
for (int i = sy + len; i < sy + len * 2; i++)
for (int j = sx; j < sx + len; j++)
s[i][j] = '*';
}
else draw(num / 5, sx, sy+len, len / 2);
}
if (dir == 4)
{
if (num / 5 == 0)
{
for (int i = sy+len; i < sy + len*2; i++)
for (int j = sx+len; j < sx + len*2; j++)
s[i][j] = '*';
}
else draw(num / 5, sx+len, sy+len, len / 2);
}
}
void getMp( int n)
{
int num;
while (cin >> num && num != -1)
{
draw(num, 0, 0, n/2);
}
}
int main()
{
//freopen("cin.txt", "r", stdin);
//freopen("cout.txt", "w", stdout);
int T = 1;
while (cin >> n && n != 0)
{
if(T != 1)
cout << endl;
init();
if (n > 0)
{
for (int i = 0; i < n; i++)
{
cin >> s[i];
}
buildTree(0, 0, (n+1)/2, 0,1);
sort(ans.begin(), ans.end());
cout << "Image " << T << endl;
if (!ans.empty())
{
cout << ans[0];
for (int i = 1; i < ans.size(); i++)
{
if (i % 12 == 0)
cout << ans[i];
else
cout << " " << ans[i];
if ((i + 1) % 12 == 0 && i + 1 < ans.size())
cout << endl;
}
cout << endl;
}
cout << "Total number of black nodes = " << cnt << endl;
}
else {
n = -n;
getMp( n+1);
cout << "Image " << T << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
cout << s[i][j];
cout << endl;
}
}
T++;
}
return 0;
}