码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 140 带宽

时间:2015-03-07 20:02:45      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:uva   回溯   递归   暴力求解   排列   

题意:参考之前讲回溯法的最后一个问题。

思路:枚举全排列,考察每一种排列下的结果。  也可以进行剪枝优化,也是参见之前讲回溯法的部分。

这里我是用二维数组g来存边关系,但顶点还是单独保存在一个数组里,然后排序,然后求排列。

这题居然交了9次,1CE1TLE1AC6WA,CE的原因是没有包含cstring,在本地没包含可以。。。TLE原因是没有注释掉freopen。WA的原因之前一直以为是输出有问题,因为找了很多数据都通过了,以及题目说最多8个结点,但是图还是要开26X26啊。。。一次一次修改,虽然WA,但程序跑的时间变长些了,然后在第88行,i 的初始值开始写的是cur+1,改为0的时候,WA了,但是时间也变长了,由此才发现问题。就是结点在图矩阵中的下标和结点数组nd中的下标搞混了。找的数据都通过的原因,可能是数据构造的不好,都是顺序的,只有一个AZ的,其他好像都是顺序的,可能没有凸显下标混淆的问题。。。(之前找不到问题,甚至猜是不是输入中含空格。。。应该不是,因为别人用scanf都可以AC)

综上,此题应注意的地方:一、图数组至少开26X26,二、顶点在两类数组中的下标需要注意下。

Code:

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>

void print();
int compute(int cur);
void solve();

using namespace std;

//int g[8][8];
int g[26][26];
int nd[8];
int n;
int bestwd;
int bestnd[8];

int main()
{
  //freopen("140.in","r",stdin);
  //freopen("140.out","w",stdout);
  
  char c;
  int flag=0;
  n=0;
  bestwd=1000;
  memset(g,0,sizeof(g));
  int node;
  int adjnd;
  //int num=0;
  while((c=getchar())!='#')
  {
    if(c=='\n')
    {
      sort(nd,nd+n);
      solve();
      //if(num++) printf("\n");
      print();
      flag=0;
      n=0;
      bestwd=1000;
      memset(g,0,sizeof(g));
    }
    else if(c==':')
    {
      flag=1;
    }
    else if(c==';')
    {
      flag=0;
    }
    else if(isalpha(c))
    {
      if(flag==0) node=c-'A';
      else  { adjnd=c-'A'; g[node][adjnd]=1; g[adjnd][node]=1;}
      int i=0;
      for(;i<n;++i) if(nd[i]==c-'A')  break;
      if(i>=n) nd[n++]=c-'A';
    }
  }
  return 0;
}

void solve()
{
  do
  {
    int wd=0;//该排列下,图的带宽 
    for(int i=0;i<n;++i)//当前元素在nd中的位置 
    {
      int ndwd=compute(i);
      wd=ndwd>wd?ndwd:wd;
    }
    if(wd<bestwd)
    {
      memcpy(bestnd,nd,sizeof(bestnd));
      bestwd=wd;     
    }
  }while(next_permutation(nd,nd+n));
}

int compute(int cur)
{
  int ndwd=0;
  int k=nd[cur];//当前元素在g中的位置 
  for(int i=k+1;i<26;++i)//这里是找存在的元素,是<26,不是<n 
  {
    if(g[k][i])
    {
      int j=0;//元素i在nd中的位置 
      for(;j<n;++j) if(nd[j]==i) break;
      int tempwd=j-cur>=0?j-cur:cur-j;
      ndwd=tempwd>ndwd?tempwd:ndwd;    
    }      
  }  
  return ndwd;
}

void print()
{
  for(int i=0;i<n;++i) printf("%c ",bestnd[i]+'A');
  printf("-> %d\n",bestwd);   
}
//错误代码,有些细节写错。修改成了版本2
//留着,和AC的代码对比。 
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>

void print();
int compute(int cur);
void solve();

using namespace std;

//int g[8][8];
int g[26][26];
int nd[8];
int n;
int bestwd;
int bestnd[8];

int main()
{
  freopen("140.in","r",stdin);
  freopen("140.out","w",stdout);
  
  char c;
  int flag=0;
  n=0;
  bestwd=1000;
  memset(g,0,sizeof(g));
  int node;
  int adjnd;
  //int num=0;
  while((c=getchar())!='#')
  {
    if(c=='\n')
    {
      sort(nd,nd+n);
      solve();
      //if(num++) printf("\n");
      print();
      flag=0;
      n=0;
      bestwd=1000;
      memset(g,0,sizeof(g));
    }
    else if(c==':')
    {
      flag=1;
    }
    else if(c==';')
    {
      flag=0;
    }
    else if(isalpha(c))
    {
      if(flag==0) node=c-'A';
      else  { adjnd=c-'A'; g[node][adjnd]=1; g[adjnd][node]=1;}
      int i=0;
      for(;i<n;++i) if(nd[i]==c-'A')  break;
      if(i>=n) nd[n++]=c-'A';
    }
  }
  return 0;
}

void solve()
{
  do
  {
    int wd=0;//该排列下,图的带宽 
    for(int i=0;i<n;++i)
    {
      int ndwd=compute(i);
      wd=ndwd>wd?ndwd:wd;
    }
    if(wd<bestwd)
    {
      memcpy(bestnd,nd,sizeof(bestnd));
      bestwd=wd;     
    }
  }while(next_permutation(nd,nd+n));
}

int compute(int cur)
{
  int ndwd=0;
  int k=0;//当前元素在nd中的位置 
  for(;k<n;++k) if(nd[k]==cur) break;
  for(int i=0;i<26;++i)//这里是找存在的元素,是<26,不是<n 
  {
    if(g[cur][i])
    {
      int j=0;//元素i在nd中的位置 
      for(;j<n;++j) if(nd[j]==i) break;
      int tempwd=j-k>=0?j-k:k-j;
      ndwd=tempwd>ndwd?tempwd:ndwd;    
    }      
  }  
  return ndwd;
}

void print()
{
  for(int i=0;i<n;++i) printf("%c ",bestnd[i]+'A');
  printf("-> %d\n",bestwd);   
}



UVa 140 带宽

标签:uva   回溯   递归   暴力求解   排列   

原文地址:http://blog.csdn.net/buxizhizhou530/article/details/44119007

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!