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; }
在做题的过程中忘了初始化,害得我调了很久都没有得出正确的结果,
以后在做题的过程中一定要注意。
这个题目我主要是卡在了那个递归的过程上,这个方面的思维训练还
应该加强。
相关文章推荐
- acm pku 2479解题报告
- ACM pku 1007 解题报告(给像我一样的新手们的忠告)
- ACM pku 1067 解题报告(威佐夫博奕(Wythoff Game))
- ACM pku 1005 解题报告
- ACM pku 1004 解题报告
- acm pku 1032 Parliament 解题报告
- Sum - ACM PKU 1844 解题报告
- acm pku 2418解题报告
- ACM pku 1658 解题报告(另一种输入输出方式)
- ACM pku 1140 解题报告(Expanding Fractions )
- acm pku 1321解题报告 棋盘问题
- acm pku 1423解题报告
- [leetcode] 139. Word Break 解题报告
- HDU 5781 数学期望+DP 解题报告
- An Easy Task解题报告
- Codeforces Round #327 (Div. 1) 解题报告
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
- 顶嵌杯决赛瑞星工程师高质量解题报告(二)
- HDU1026 Ignatius and the Princess I 解题报告--bfs
- [leetcode] 62. Unique Paths 解题报告