POJ 1128 Frame Stacking

    技术2022-05-13  5

    /*

    http://acm.pku.edu.cn/JudgeOnline/problem?id=1128

    DFS回溯实现拓扑排序 */ #include <iostream> #include <memory> #include <string> #include <algorithm> #define MAX_N 32 #define MAX_L 26 using namespace std; char mapv[MAX_N + 1][MAX_N + 1];  //记录输入 char letter[MAX_L + 1];           //记录输入中输出的字母c, C - 'A' + 1 bool graph[MAX_L + 1][MAX_L + 1]; //graph[i][j] = true, 表示i frame 排在 j frame的上面 int rowN, colN, lNum, resNum;     //输入的行数,列数,lnum表述输入中出现的字母的类别数,resNum记录输出的结果数目 int pos[MAX_L + 1][4];            //记录各个字母上下左右的Index, 从1开始记录 bool v[MAX_L + 1]; //记录结果 struct node {     string seq;     node()     {         seq = "";     } }res[200]; //从0开始存 void init() {     resNum = lNum = 0;     memset(pos, 0, sizeof(pos));     memset(graph, 0, sizeof(graph)); } bool compare(const node n1, const node n2) {     if(n1.seq <= n2.seq)         return true;     return false; } void topSort(int layer, string seqStr) {     //排完了,每排一个字母,layer + 1, 直到排完所有的字母     if(layer > lNum)     {         //记录结果         res[resNum++].seq = seqStr;         return;     }     int minCom = INT_MAX, s, k, curL, curCom;     int minNum = 0;     //向temp这类数据必须使用局部数据,应为没一层的temp必须不能受其他层影响,     //一开把temp设成了全局的,这样进入下一层后,下一层可能会修改上面层的temp,从而产生错误结果     int temp[MAX_L + 1];     //寻找入度最小的点,这个点对应的frame应该是放在最上面的frame(可能不唯一,所以会产生多个结果)     for(s = 0; s < lNum; s++)     {         //当前结点是上面已经处理过已经被抹去的点         if(letter[s] == '.')             continue;         curCom = 0;         curL = letter[s] - 'A' + 1;         for(k = 1; k <= MAX_L; k++)             if(graph[k][curL])                 curCom++;         //找到更小入度的点         if(curCom < minCom)         {             minCom = curCom;             minNum = 1;             temp[minNum] = curL; //temp 从1开始存         }         //和最小度数相等,则记录,并使minNum + 1         else if(curCom == minCom)         {             temp[++minNum] = curL;         }     }     //回溯遍历所有的当前入度最小的点     seqStr = "." + seqStr;     for(s = 1; s <= minNum; s++)     {         curL = temp[s];         //copyR和copyC也必须是局部数,原因和temp相同         bool copyR[MAX_L + 1], copyC[MAX_L + 1];         memset(copyR, 0, sizeof(copyR));         memset(copyC, 0, sizeof(copyC));         //保存当前节点对应的数据,并置位         for(k = 1; k <= MAX_L; k++)         {             copyR[k] = graph[curL][k];             copyC[k] = graph[k][curL];             graph[curL][k] = graph[k][curL] = false;         }         seqStr[0] = curL - 1 + 'A';         //已经处理过的节点要摸去         int tempPos;         for(k = 0; k < lNum; k++)         {             if(letter[k] == curL - 1 + 'A')             {                 tempPos = k;                 letter[k] = '.';                 break;             }         }         //dfs         topSort(layer + 1, seqStr);         //恢复相关数据         letter[tempPos] = curL - 1 + 'A';         for(k = 1; k <= MAX_L; k++)         {             graph[curL][k] = copyR[k];             graph[k][curL] = copyC[k];         }     } } int main() {     int i, j, k;     char c, cc;     while(cin>>rowN)     {         cin>>colN;         //input process         init();         for(i = 1; i <= rowN; i++)         {             for(j = 1; j <= colN; j++)             {                 cin>>c;                 mapv[i][j] = c;                 if(c >= 'A' && c <= 'Z')                 {                     for(k = 0; k < lNum; k++)                         if(letter[k] == c)                             break;                     if(k >= lNum)                         letter[lNum++] = c;                 }             }         }         ///寻找每个frame最上方和最下方的行号,已经最左边和最右边的列号         int s, p0, p1, p2, t, curL;         //扫描行         for(i = 1; i <= rowN; i++)         {             //扫描任意列             for(j = 1; j <= colN; j++)             {                 c = mapv[i][j];                 cc = mapv[rowN - i + 1][j];                 if(c >= 'A' && c <= 'Z')                 {                     if(pos[c - 'A' + 1][0] == 0)                         pos[c - 'A' + 1][0] = i;                 }                 if(cc >= 'A' && cc <= 'Z')                 {                     if(pos[cc - 'A' + 1][1] == 0)                         pos[cc - 'A' + 1][1] = rowN - i + 1;                 }             }         }         //列扫描         for(i = 1; i <= colN; i++)         {             //扫描任意行             for(j = 1; j <= rowN; j++)             {                 c = mapv[j][i];                 cc = mapv[j][colN - i + 1];                 if(c >= 'A' && c <= 'Z')                 {                     if(pos[c - 'A' + 1][2] == 0)                         pos[c - 'A' + 1][2] = i;                 }                 if(cc >= 'A' && cc <= 'Z')                 {                     if(pos[cc - 'A' + 1][3] == 0)                         pos[cc - 'A' + 1][3] = colN - i + 1;                 }             }         }         ///顺次处理每个节点s,如果在s的四条边线中夹杂有其他节点t,那么表示         //t遮住了s, graph[t][s] 设置为true         for(s = 0; s < lNum; s++)         {             curL = letter[s] - 'A' + 1;             memset(v, 0, sizeof(v));             for(i = 0; i < 4; i++)             {                 p0 = pos[curL][i];                 int j = ((int(i / 2) + 1) * 2) % 4;                 p1 = pos[curL][j];                 p2 = pos[curL][j + 1];                 for(t = p1; t <= p2; t ++)                 {                     if(i <= 1)                     {                         if(mapv[p0][t] == letter[s])                             continue;                         if(v[mapv[p0][t] - 'A' + 1])                             continue;                         if(!(mapv[p0][t] >= 'A' && mapv[p0][t] <= 'Z'))                             continue;                         v[mapv[p0][t] - 'A' + 1] = true;                         graph[mapv[p0][t] - 'A' + 1][curL] = true;                     }                     else                     {                         if(mapv[t][p0] == letter[s])                             continue;                         if(v[mapv[t][p0] - 'A' + 1])                             continue;                         if(!(mapv[t][p0] >= 'A' && mapv[t][p0] <= 'Z'))                             continue;                         v[mapv[t][p0] - 'A' + 1] = true;                         graph[mapv[t][p0] - 'A' + 1][curL] = true;                     }                 }                             }         }         string str = "";         topSort(1, str);         sort(res, res + resNum, compare);         for(i = 0; i < resNum; i++)             cout<<res[i].seq<<endl;         /     }     return 0; }


    最新回复(0)