您的位置:首页 > 其它

acm pku 1128解题报告

2009-03-06 07:26 253 查看
这个题目我想了很久,后来经过多次请教我的师兄才把它弄出来。

具体思路是,先根据字母所在的位置来找出它所对应的矩形的左上角和

右下角坐标。然后在这个矩形里面找与之不同的其它字母,由它们之间

的联系来建图,并记录字母的个数,即可得出该结点的入度。最后运用

递归的方法来对它进行拓扑排序,在递归的过程中,把所有的结果记录

下来,最后再按照要求输出。代码如下:
#include <iostream>
#include <algorithm>
#include <string>
#include <map>

using namespace std;

template <class T> void out(T x, int n){    for (int i = 0; i < n; ++i) cout << x[i] << ' ';    cout << endl;   }
template <class T> void out(T x, int n, int m){ for (int i = 0; i < n; ++i) out(x[i], m);   cout << endl;   }

#define OUT(x) (cout << #x << " = " << x << endl)

typedef map<char,int> Mymap;
Mymap nums;
char Mar[30][30];
int pres[30][30];

struct Node
{
int x_min,y_min,x_max,y_max;
char C;
};
Node dat[30];
int top[30];
char arr[120][30];
int counter;
char str[30];
bool visit[30];

int compare(const void *s1,const void *s2)
{
return strcmp(((char *)s1),((char *)s2));
}
void dfs(int k,int total)
{
int ans[30];
int front[30];
if(k == total)
{
int r=0;
for(int i = k-1;i>=0;--i,r++)
arr[counter][r] = str[i];
counter++;
return;
}
for(int i=0;i<total;++i)
{
if(top[i] == 0 && !visit[i])
{
visit[i] = true;
str[k] = dat[i].C;

for(int j=0;j<total;++j)
{
ans[j] = pres[i][j];
front[j] = top[j];
if(pres[i][j] == 1)
{
top[j]--;
pres[i][j] = 0;
}
}
top[i] = -1;
dfs(k+1,total);
top[i] = 0;
for(int j=0;j<total;++j)
{
pres[i][j] = ans[j];
top[j] = front[j];
}
visit[i] = false;
}
}
}
void conversation(int n)
{
memset(top,0,sizeof(top));
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
pres[i][j] = 0;
bool used[30];
for(int i=0;i<n;++i)
{
memset(used,false,sizeof(used));
char ch;
for(int j=dat[i].x_min;j<=dat[i].x_max;++j)
{
ch = Mar[j][dat[i].y_min];
if(ch!='.' && ch!=dat[i].C)
{
if(used[ch-'A'] == false)
{
top[i]++;
used[ch-'A'] = true;
pres[nums[ch]][i] = 1;
}

}
ch = Mar[j][dat[i].y_max];
if(ch!='.' && ch!=dat[i].C)
{
if(used[ch-'A'] == false)
{
top[i]++;
used[ch-'A'] = true;
pres[nums[ch]][i] = 1;
}
}
}
for(int k=dat[i].y_min+1;k<dat[i].y_max;++k)
{
ch = Mar[dat[i].x_min][k];
if(ch!='.' && ch!=dat[i].C)
{
if(used[ch-'A'] == false)
{
top[i]++;
used[ch-'A'] = true;
pres[nums[ch]][i] = 1;
}
}
ch = Mar[dat[i].x_max][k];
if(ch!='.' && ch!=dat[i].C)
{
if(used[ch-'A'] == false)
{
top[i]++;
used[ch-'A'] = true;
pres[nums[ch]][i] = 1;
}
}
}
}

memset(visit,false,sizeof(visit));
counter = 0;
memset(arr,0,sizeof(arr));
dfs(0,n);
qsort(arr,counter,30,compare);
for(int i=0;i<counter;++i)
{
for(int j=0;j<n;++j)
cout<<arr[i][j];
cout<<endl;
}
}
void input()
{
int h,w;
while(cin>>h>>w)
{
int k=0;
bool f[30];
memset(f,false,sizeof(f));
memset(Mar,0,sizeof(Mar));
memset(dat, 0, sizeof(dat));

for(int i=0;i<h;++i)
for(int j=0;j<w;++j)
{
cin>>Mar[i][j];

if(Mar[i][j]!='.')
{
int temp = Mar[i][j]-'A';
if(!f[temp])
{
dat[k].C = Mar[i][j];
dat[k].x_min = i;
dat[k].y_min = j;
dat[k].x_max = i;
dat[k].y_max = j;
f[temp] = true;
nums[Mar[i][j]] = k;
k++;
}
else{
int lc = nums[Mar[i][j]];
if(i<dat[lc].x_min)
dat[lc].x_min = i;
if(j<dat[lc].y_min)
dat[lc].y_min = j;
if(i>dat[lc].x_max)
dat[lc].x_max = i;
if(j>dat[lc].y_max)
dat[lc].y_max = j;
}
}

}
conversation(k);
}
}
int main()
{
input();
return 0;
}


在做题的过程中忘了初始化,害得我调了很久都没有得出正确的结果,

以后在做题的过程中一定要注意。

这个题目我主要是卡在了那个递归的过程上,这个方面的思维训练还

应该加强。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: