心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0
调试了将近一个小时!我美好的一个夜晚啊!就这样浪费了!
而不断WA的原因竟然是因为输出格式问题!最后一组数据后面多了一个回车!
再次抱怨ACM的多组数据测试!抱怨全文比较!抱怨不提示PE提示WA!
好了,STOP!
这题BFS求最短路即可。虽然可能有25000个单词,相当于25000个结点,构图的话空间肯定不够,时间也不允许。但是因为单词长度不同的肯定不会是doublet,所以平均下来一个图的结点数大约25000/16个,O(n^2)的算法足够了。
在读入是就把不同长度的单词分开,BFS让字符串进队列,只需要让该字符串所在位置编号入队即可。
以下是我的代码:
#include<iostream>
#include
<fstream>
#include
<string>
#include
<bitset>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define maxl 17
#define maxn 25147
using namespace std;

typedef 
struct
{
    
long counter,front,rear,pos[maxn];
}queue;
void Clear(queue &q)
{
    q.counter
=0;q.front=0;q.rear=-1;
}
bool Empty(queue &q)
{
    
return (q.counter==0);
}
void Push(queue &q,long x)
{
    q.counter
++;
    q.rear
++;
    q.pos[q.rear]
=x;
}
void Pop(queue &q,long &x)
{
    q.counter
--;
    x
=q.pos[q.front];
    q.front
++;
}

long T=0,cnt[maxl];
string word[maxl][maxn];
queue q;

bool doublet(string &a,string &b)
{
    
long l=a.length(),diff=0;
    
for(long i=0;i<l;i++)
      
if(a[i]!=b[i])
      {
         diff
++;
         
if(diff>=2return false;
      }
    
if(!diff) return false;
    
return true;
}

int main()
{
    memset(cnt,
0,sizeof(cnt));
    
    
string t;
    
while(getline(cin,t)&&!t.empty())
    {
       cnt[t.length()]
++;
       word[t.length()][cnt[t.length()]]
=t;
    }
    
string a,b;
    
while(cin>>a>>b)
    {
       T
++;
       
long la=a.length(),pa,lb=b.length(),pb;
       
long d[maxn],f[maxn];
       
bool used[maxn];
       
       
if(la!=lb)
       {
          
if(T>=2) cout<<endl;
          cout
<<"No solution."<<endl;
          
continue;
       }
       
       
for(pa=1;pa<=cnt[la];pa++)
         
if(word[la][pa]==a)
           
break;
       
for(pb=1;pb<=cnt[la];pb++)
         
if(word[la][pb]==b)
           
break;
       
if(pa>cnt[la]||pb>cnt[la])
       {
          
if(T>=2) cout<<endl;
          cout
<<"No solution."<<endl;
          
continue;
       }
       
       memset(d,
-1,sizeof(d));
       memset(f,
0,sizeof(f));
       memset(used,
false,sizeof(used));
       Clear(q);
       Push(q,pa);d[pa]
=0;f[pa]=0;used[pa]=true;
       
while(!Empty(q))
       {
          
long r;
          Pop(q,r);
          
for(long i=1;i<=cnt[la];i++)
            
if(!used[i]&&doublet(word[la][r],word[la][i]))
            {
               Push(q,i);
               d[i]
=d[r]+1;
               f[i]
=r;
               used[i]
=true;
            }
          
if(d[pb]!=-1break;
       }
       
if(d[pb]==-1)
       {
          
if(T>=2) cout<<endl;
          cout
<<"No solution."<<endl;
       }
       
else
       {
          
if(T>=2) cout<<endl;
          
long num=0,ans[maxn];
          num
++;ans[num]=pb;
          
while(f[pb])
          {
             num
++;ans[num]=f[pb];
             pb
=f[pb];
          }
          
for(long i=num;i>=1;i--)
            cout
<<word[la][ans[i]]<<endl;
       }
    }
return 0;
}
posted on 2010-11-15 00:02 lee1r 阅读(1062) 评论(3)  编辑 收藏 引用 所属分类: 题目分类:图论

FeedBack:
# re: UVa 10150 Doublets
2010-11-15 11:50 | Tanky Woo
为何感觉你每次题目的代码都很长呢?是题目太难了吗?

还以为你一直没写博客了,没想到还在继续写。呵呵。  回复  更多评论
  
# re: UVa 10150 Doublets
2010-11-15 12:16 | Lee1R
@Tanky Woo
因为这题需要用队列,队列的函数都得写。ACM当然可以直接#include<queue>,但是OI不允许这样用啊,必须自己写。而且ACM的题目很注重细节,需要把各种可能的情况全都考虑。再者这道题不仅要求最优值,还要求输出最优解,就必须记录路径……程序就长了。

还有5天就是NOIP2010了,我必须得准备啊~我确实很久没有写程序了。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理