429 - Word Transformation

All about problems in Volume 4. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

konsept
New poster
Posts: 22
Joined: Wed Dec 19, 2001 2:00 am
Location: Waterloo, Canada
Contact:

"Word Transformation" (problem 429)

Post by konsept »

I can't figure out why I get a WA with my solution.
the basic idea is to treat the words as a graph, with edges between 2 words iff they differ by exactly 1 letter. once we tranform it into graph form we can apply the FLoyd Warshall O( n^3 ) algorithm to find the best way of transorming any word to any other word.

[cpp]#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <iostream>

using namespace std;

int cnt( string a, string b ){
if ( a.size() != b.size() ) return 0;
int x=0;
for ( int i=0; i<a.size(); i++ )
x+= (a!=b);
return x;
}

int dist[201][201];
map< string, int > ind;
vector<string> w;

int main( void ){
FILE *in=stdin;

int i,j,k,n;

n=0;
while ( 1 ){
string m;
char c[512];
fscanf( in, "%s", c );
m=c;
if ( m=="*" ) break;

ind[ m ]=n;
w.push_back( m );
dist[n][n]=0;

for ( i=0; i<n; i++ ){
k=cnt(w,w[n]);
if ( k==1 ){
dist[n]=dist[n]=1;
// printf( "linkF: %s %s\n", w.c_str(), w[n].c_str() );
}
else
dist[n]=dist[n]=10000001;
}

n++;
}

for ( k=0; k<n; k++ )
for ( i=0; i<n; i++ )
for ( j=0; j<n; j++ )
dist[j]=min( dist[j], dist[i][k]+dist[k][j] );

char a[512],b[512];

while ( 2==fscanf( in, "%s %s", a,b ) ){
string x=a; string y=b;
printf( "%s %s %d\n", a,b,dist[ ind[x] ][ ind[y] ] );
}

return 0;
}[/cpp]

Stefan Pochmann
A great helper
Posts: 284
Joined: Thu Feb 28, 2002 2:00 am
Location: Germany
Contact:

Post by Stefan Pochmann »

Long live multiple input, for the joy of all of us!

konsept
New poster
Posts: 22
Joined: Wed Dec 19, 2001 2:00 am
Location: Waterloo, Canada
Contact:

how?

Post by konsept »

the problem statement states that after the pairs of words there is a EOF
so how can you have multiple input??

assuming its possible to have multiple input how can you distinguish between the end of the pairs of words section and the start of a new data set?

you can answer this by modifying my code for me to handle multiple inputs, if you want :)

Stefan Pochmann
A great helper
Posts: 284
Joined: Thu Feb 28, 2002 2:00 am
Location: Germany
Contact:

Post by Stefan Pochmann »

Read the description of multiple input format. There is a blank line between the inputs, that's how you know when to start all over again.

konsept
New poster
Posts: 22
Joined: Wed Dec 19, 2001 2:00 am
Location: Waterloo, Canada
Contact:

forget this

Post by konsept »

so now I have to worry about blank lines??
forget this problem.

Stefan Pochmann
A great helper
Posts: 284
Joined: Thu Feb 28, 2002 2:00 am
Location: Germany
Contact:

Post by Stefan Pochmann »

Oh, come on... Just read the complete line with "gets" or "getline" and then use "sscanf" or an "istringstream" to check for empty line and to read the two words.

Pupirev Sergei
New poster
Posts: 24
Joined: Mon Feb 24, 2003 5:08 pm

429

Post by Pupirev Sergei »

I can't understand why WA. I use usual Floyd algorithm
[cpp]#include <fstream.h>
#include <string.h>
#define max 201
//#define cin in
//ifstream in("input.txt");
int a[max][max];
int n;

void floyd()
{
int i,j,k;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
for (k=0;k<n;k++)
if (a[j]>a[k]+a[k][j]) a[j]=a[k]+a[k][j];
}

char dic[max][11];
int kol=0;
int bs(char *s)
{
int i;
for (i=0;i<kol;i++)
if (strcmp(dic,s)==0) return i;
return -1;
}
int ok(char *s1,char *s2)
{
int r=0,i;
if (strlen(s1)!=strlen(s2)) return 0;
for (i=0;i<strlen(s1);i++)
if (s1!=s2) r++;
if (r==1) return 1;
return 0;
}
void read(char *s,char *s1,char *s2)
{
int i=0;
while (s>'z' || s<'a') i++;
int j=0;
while (s<='z' && s[i]>='a') {s1[j]=s[i];i++;j++;}
s1[j]=0;
while (s[i]>'z' || s[i]<'a') i++;
j=0;
while (i<strlen(s) && s[i]<='z' && s[i]>='a') {s2[j]=s[i];i++;j++;}
s2[j]=0;
}
int main()
{
int ntest,t;
cin>>ntest;
for (t=0;t<ntest;t++){
if (t!=0) cout<<"\n";
kol=0;n=0;
int i;
cin>>dic[kol];
while (dic[kol][0]!='*')
{
kol++;
cin>>dic[kol];
}
n=kol;
int j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (i!=j) a[i][j]=10000;
else a[i][j]=0;
for (i=0;i<n;i++)
for (j=i+1;j<n;j++)
if (ok(dic[i],dic[j])==1)
{
a[i][j]=1;
a[j][i]=1;
}

char s1[11],s2[11];
char s3[30];
cin.getline(s3,30);
cin.getline(s3,30);
floyd();
while (strlen(s3)!=0)
{
read(s3,s1,s2);
int k1=bs(s1);
int k2=bs(s2);
cout<<s1<<" "<<s2<<" "<<a[k1][k2]<<"\n";
cin.getline(s3,30);
}
}
return 0;
}[/cpp]

the LA-Z-BOy
Learning poster
Posts: 94
Joined: Wed Jul 31, 2002 12:44 pm
Location: Dacca, Bangladesh
Contact:

Post by the LA-Z-BOy »

your floyd algorithm is wrong here...the intermediate node selection loop (k=0; k<... in your code) should be the outer most loop and also you are not creating new paths where direct edge is not possible.
so modifying a little your floyd algo should be ok[cpp]void floyd()
{
int i,j,k;
for (k=0;k<n;k++)
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (a[j]==0 || a[j]>a[k]+a[k][j])
a[j]=a[k]+a[k][j];
}
[/cpp]
greetings :wink:
Istiaque Ahmed [the LA-Z-BOy]

Pupirev Sergei
New poster
Posts: 24
Joined: Mon Feb 24, 2003 5:08 pm

Post by Pupirev Sergei »

Thanks, a lot!
It is so funny bug!
But i should not write if (a[j]==0 || ...) as first i have a[j]=10000 (infinity).

the LA-Z-BOy
Learning poster
Posts: 94
Joined: Wed Jul 31, 2002 12:44 pm
Location: Dacca, Bangladesh
Contact:

Post by the LA-Z-BOy »

oh sorry, i missed that.
Istiaque Ahmed [the LA-Z-BOy]

Junayeed
New poster
Posts: 50
Joined: Sat Oct 26, 2002 9:02 am
Location: Dhaka, Bangladesh

429 - Word Transformation

Post by Junayeed »

I try to solve this problem. But i am getting RTE.
Please help me with some multiple inputs.

Thanks.

juli3079fe
New poster
Posts: 1
Joined: Tue Dec 09, 2003 11:54 am

429 - WA

Post by juli3079fe »

Hello guys,
I sent the following code and i got WA, is there anyone has any idea why?
[cpp]
#include <cstdio>
#include <vector>
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
using namespace std;

typedef struct{
char words[11];
bool visited;
int dist;
vector<int> neigh;
}Word;

typedef struct{
Word wlist[10][200];
int size[10];
}WList;


int search_path(WList *wl, int len, int spos, int tpos){
int pos;
int count;
int path = 1;
vector<int>::iterator en;
vector<int>::iterator bg;
bool found = false;
queue<int> q;
q.push(spos);

for(int i=0;i<200;i++) wl->wlist[len].visited = false;

wl->wlist[len][spos].visited = true;
wl->wlist[len][spos].dist = 0;
while(!q.empty()){
pos = q.front();
q.pop();
en = wl->wlist[len][pos].neigh.end();
bg = wl->wlist[len][pos].neigh.begin();
for(vector<int>::iterator it=bg;it!=en;it++){
if(!wl->wlist[len][*it].visited){
path=wl->wlist[len][*it].dist = wl->wlist[len][pos].dist+1;
count = 0;
for(int i=0;i<=len;i++){
if(wl->wlist[len][tpos].words == wl->wlist[len][*it].words) count++;
}

if( count == (len+1) ) {
found = true;
goto outerloop;
}
q.push(*it);
wl->wlist[len][*it].visited = true;
}
}
}

outerloop:
if(found) return path;
return 0;
}

int main(int argc,char **argv){

char input[50];
char temp[50];
WList dict;
size_t len;
string output = "";
char *pin;
char src[11],target[11];
for(int i=0;i<10;i++) dict.size = 0;
while(true){
fgets(input,50,stdin);
if(strlen(input) > 1)
input[strlen(input)-1] = '\0';
if(strcmp(input,"*") == 0) break;
len = strlen(input);
int dist;
if(dict.size[len-1] > 0){
strncpy(dict.wlist[len-1][dict.size[len-1]].words,input,len);
for(int j=0;j<=dict.size[len-1];j++){
int count = 0;
for(int k=0;k<len;k++)
if(dict.wlist[len-1][j].words[k] != input[k]) count++;
if(count == 1){
dict.wlist[len-1][j].neigh.push_back(dict.size[len-1]);
dict.wlist[len-1][dict.size[len-1]].neigh.push_back(j);
}
}
dict.size[len-1]++;
}
else{

strncpy(dict.wlist[len-1][0].words,input,len);
dict.size[len-1]++;
}
}
while(true){
fgets(input,50,stdin);
if(feof(stdin)) break;
if(strlen(input) > 1) input[strlen(input)-1] = '\0';
sscanf(input,"%s %s",src,target);
size_t srclen = strlen(src);
int srcpos = 0;
int tarpos = 0;
for(int j=0;j<dict.size[srclen-1];j++){
if(strcmp(dict.wlist[srclen-1][j].words,src) == 0){
srcpos = j;
break;
}
}

for(int j=0;j<dict.size[srclen-1];j++){
if(strcmp(dict.wlist[srclen-1][j].words,target) == 0){
tarpos = j;
break;
}
}

int bpath = search_path(&dict,srclen-1,srcpos,tarpos);
sprintf(temp,"%s %s %d\n",src,target,bpath);
output += temp;
}
cout << output;
}

Thank you in advance :lol: [/cpp]

sohel
Guru
Posts: 856
Joined: Thu Jan 30, 2003 5:50 am
Location: New York

Post by sohel »

Hi Juli,

I might be wrong but I don't think you are handling this program as a 'multiple input problem'. If you look closely beside the probelm name you will see a blue tick. It indicates multiple input form.

If you are a newcomer then you will find this useful.
Multiple input fomat:

N

CASE 1

CASE 2

CASE N

-- where N indicates the number of test cases.

The consecutive outputs are seperated by a blank line.
:wink:

bornagirl2397
New poster
Posts: 2
Joined: Fri Mar 07, 2003 9:14 am
Location: republic of korea

problem 429 WA help me~

Post by bornagirl2397 »

i used floyd to search for the shortest transformation..
but always got WA..

are there tricky inputs ??
please help me solving problem!!

code is attached below..

[cpp]
#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

#define INFINITY 1000000

bool Trans(char *a, char *b)
{
int len,i,cnt=0;
len=strlen(a);
for(i=0;i<len;i++)
if(a!=b) cnt++;
return (cnt==1?true:false);
}

void main()
{
char dic[210][15],word1[15],word2[15];
int map[210][210]={0,};
int wordCnt=0,i,j,k,caseno;

cin>>caseno;
while(caseno--){
while(cin>>dic[wordCnt] && dic[wordCnt][0]!='*') wordCnt++;

for(i=0;i<210;i++)
for(j=0;j<210;j++)
if(i!=j) map[j]=INFINITY;

for(i=0;i<wordCnt;i++)
for(j=i+1;j<wordCnt;j++)
if(strlen(dic)==strlen(dic[j]) && Trans(dic,dic[j]))
map[j]=map[j]=1;

for(k=0;k<wordCnt;k++)
for(i=0;i<wordCnt;i++)
for(j=0;j<wordCnt;j++)
if(map[k]+map[k][j]<map[j])
map[j]=map[i][k]+map[k][j];

while(cin>>word1>>word2){
// if(word1[0]=='0') break;
for(i=0;strcmp(dic[i],word1) && i<wordCnt;i++);
for(j=0;strcmp(dic[j],word2) && j<wordCnt;j++);
cout<<word1<<" "<<word2<<" "<<map[i][j]<<endl;
}
wordCnt=0;
}
}
[/cpp]
aaa

jaracz
Learning poster
Posts: 79
Joined: Sun Sep 05, 2004 3:54 pm
Location: Poland

429 RTE!!

Post by jaracz »

hi !
I don't see the reason I'm gettin' RTE
anyone do?

Code: Select all

#include <stdio.h>
#include <string.h>

#define MAX 201
#define LIMIT 11

char library[MAX][LIMIT];
char check[MAX][LIMIT];
char current[LIMIT];

int how;
int j = 0;
int d = 0;

int main(void)
{
    scanf("%d",&how);
    for(int a = 0; a < how; a++)
    {
        int i = 0;
        while(scanf("%s",&library[i]))
        {
            if(library[i][0]=='*')
            break; 
            i++;
        }
        i--;
        while(scanf("%s%s",&check[j],&check[j+1])==2)
        {
            j+=2;
        } 
        for(d = 0; d < j; d++){
        int quantity = 0;
        for(int a = 0; a < LIMIT; a++)
        current[a] = check[d][a];
        for(int b = 0; b <= i; b++)
        {
            int count = 0;
            for(int c = 0; c < LIMIT; c++)
            if(current[c]!=library[b][c])
            count++;
            if(count==1)
            {
                int i;
                for(i = 0; i < strlen(library[b]); i++)
                current[i] = library[b][i];
                for(i = 0; i < strlen(current); i++)
                library[b][i] = '\0';
                quantity++;
            }    
        }    
        printf("%s %s %d\n",check[d],check[d+1],quantity);
        d++;
        }    
    }   
    return 0; 
}    
keep it real!

Post Reply

Return to “Volume 4 (400-499)”