Yes usually there is a newline right before EOF but I wouldn't count on it.
Try simplifying your code as I described before. Also try changing your input parsing to just use C I/O. I only used scanf, getchar, gets, and printf in my AC code, no cin.
843 - Crypt Kicker
Moderator: Board moderators
-
- Guru
- Posts: 5947
- Joined: Thu Sep 01, 2011 9:09 am
- Location: San Jose, CA, USA
Re: 843 - Crypt Kicker
Check input and AC output for thousands of problems on uDebug!
Crypt Kicker Judging Problem
Is the judge misjudging the problem crypt kicker, i've tested my solution over and over but the judge keeps telling me its wrong, I even copied a correct solution and submitted it but still wrong answer. Here is my solution. If you can test my solution or find a problem with it please do.
Code: Select all
#include <stdio.h>
#include <string.h>
typedef char word[17];
word dict[1001];
word words[100];
char line[81];
char linep[81];
char map[26], mapinv[26];
int at[17], count[17];
int n, i, j, len1, len2, letters_line;
int backtrack, nwords_line, solution;
char * cp;
int cmp(const void * x, const void * y)
{
return (strlen((char *)x)-strlen((char *)y));
}
int count_letters(char * L)
{
int l[26], c=0, k;
char * cp = L;
memset(l, 0, sizeof(int)*26);
for(; *cp; cp++)
{
if(*cp == ' ') continue;
l[*cp -'a']=1;
}
for(k=0;k<26;k++) if(l[k])c++;
return c;
}
void print_stars()
{
char * cp = linep;
for(;*cp; cp++)
{
if(*cp == ' ') printf(" ");
else printf("*");
}
printf("\n");
}
int is_solution(char * m, char * minv)
{
int x = 0, y;
for(y=0;y<26;y++)
{
if(!m[y]) continue;
x++;
}
return x==letters_line;
}
void process_solution(char * m, char * minv)
{
char * cp = linep;
for(;*cp;cp++)
{
if(*cp == ' ') printf(" ");
else printf("%c", minv[*cp-'a']);
}
printf("\n");
}
int done;
void search(int k, char * m, char * minv)
{
char m_[26], minv_[26];
int I, J, LEN;
if(done || k>nwords_line+1) return;
if(is_solution(m, minv))
{
process_solution(m, minv);
done=solution=1;
}
else
{
LEN = strlen(words[k]);
for(I=at[LEN];I<at[LEN]+count[LEN];I++)
{
memcpy(m_, m, 26*sizeof(char));
memcpy(minv_, minv, 26*sizeof(char));
backtrack = 0;
for(J=0;J<LEN;J++)
{
if(!m_[dict[I][J]-'a'])
{
m_[dict[I][J]-'a'] = words[k][J];
minv_[words[k][J]-'a'] = dict[I][J];
}
else if(m_[dict[I][J]-'a'] != words[k][J])
{
backtrack=1; break;
}
}
if(!backtrack) search(k+1, m_, minv_);
}
}
}
int empty(char * x)
{
char * c = x;
for(; *c; c++) if(*c != ' ' && *c != '\n') return 0;
return 1;
}
int main()
{
for(i = 0; i < 17; i++) { at[i] = 0; count[i] = 0; }
scanf("%d\n", &n);
for(i = 1; i <= n; i++) { scanf("%s\n", dict[i]); count[strlen(dict[i])]++; }
qsort(dict+1, n, sizeof(word), cmp);
len1 = strlen(dict[1]); at[len1] = 1;
for(i = 2; i <= n; i++)
{
len2 = strlen(dict[i]);
if(len1==len2) continue;
at[len2] = i; len1 = len2;
}
while(fgets(line, 81, stdin))
{
if(empty(line)) continue;
len1 = strlen(line);
if(line[len1-1]=='\n') line[len1-1]='\0';
done=solution=0;
memset(map, 0, 26*sizeof(char));
memset(mapinv, 0, 26*sizeof(char));
letters_line = count_letters(line);
strcpy(linep, line);
nwords_line = 2;
cp = strtok(line, " ");
strcpy(words[1], cp);
while((cp=strtok(0, " "))) strcpy(words[nwords_line++], cp);
strcpy(words[nwords_line], "");
nwords_line--;
search(1, map, mapinv);
if(!solution) print_stars();
}
return 0;
}
-
- Guru
- Posts: 5947
- Joined: Thu Sep 01, 2011 9:09 am
- Location: San Jose, CA, USA
Re: Crypt Kicker Judging Problem
On problem 843, if there is a blank line in the output, my AC code would print that line and any spaces it had to the output.
Check input and AC output for thousands of problems on uDebug!
Re: Crypt Kicker Judging Problem
I figured out the problem. I was using the globals map, mapinv where I should have been using the locals m_, minv_ in the funciton search. It got accepted.
Crypt Kicker :Mis_Judging
Mr.
Master
for the program written by
the judge accepted it but it's wrong try the input
the previous program prints
but it's wrong because "dna" isn't mentioned in the dictionary
and the output should be
you can check it in your http://www.udebug.com/UVa/843
you ignored part of the problem description it sayssaadtaame
adding this to your "is_solution()" function you would get ACTo ensure that the encryption is reversible, no two letters are
replaced by the same letter.
Code: Select all
int QW;
for(y=0;y<26;y++)
for(QW=0;QW<26;QW++)
if(QW != y && m[QW] != '\0' && m[y] != '\0' && m[QW] == m[y])
return 0;
Master
i think there is another problem with the judgebrianfry713
for the program written by
after fixingsaadtaame
the judge accepted it but it's wrong try the input
Code: Select all
1
and
zxc cxz
Code: Select all
and dna
and the output should be
Code: Select all
*** ***
-
- Guru
- Posts: 5947
- Joined: Thu Sep 01, 2011 9:09 am
- Location: San Jose, CA, USA
Re: 843 - Crypt Kicker
I don't have access to the judge's I/O.
If the judge accepts wrong code it doesn't really mean that there is a problem with it, just that it doesn't test that case.
If the judge accepts wrong code it doesn't really mean that there is a problem with it, just that it doesn't test that case.
Check input and AC output for thousands of problems on uDebug!
-
- New poster
- Posts: 1
- Joined: Sat Aug 18, 2018 7:54 pm
Re: 843 - Crypt Kicker
Hi everyone
I am really stuck in this problem. I did a Java solution for it. The code seems non erroneous passing the test cases proposed by uDebug site. However, I got WA verdict on the uva. Can anyone identify the problem in the code?
Here is the code:
I am really stuck in this problem. I did a Java solution for it. The code seems non erroneous passing the test cases proposed by uDebug site. However, I got WA verdict on the uva. Can anyone identify the problem in the code?
Here is the code:
Code: Select all
import java.util.*;
public class P843 {
public static void main(String[] args) {
Scanner c = new Scanner(System.in);
int dictionarySize = c.nextInt();
c.nextLine();
// get the dictionary from the input stream:
String[] words = new String[dictionarySize];
for (int i = 0; i < words.length; i++)
words[i] = c.nextLine();
// get encrypted input
String line = c.nextLine();
while (c.hasNextLine() && line.trim().length() > 0) {
String[] eWords = line.split(" ");
String[] dWords = decryptWords(eWords, words);
for (int i = 0; i < dWords.length; i++)
if (i != dWords.length - 1) {
System.out.print(dWords[i] + " ");
} else {
System.out.println(dWords[i]);
}
line = c.nextLine();
if (line.trim().length() == 0)
System.exit(0);
}
}
private static String[] decryptWords(String[] eWords, String[] words) {
String[] dWords = new String[eWords.length];
// get copy of the dWords so that the original version not destroyed
String[] eWordsCopy = Arrays.copyOf(eWords, eWords.length);
// sort by length from the greatest to the smallest
Arrays.sort(eWordsCopy, new Comparator<String>() {
@Override
public int compare(String w1, String w2) {
return Integer.compare(w2.length(), w1.length());
}
});
// initialize a key array to hold decrypted letters:
char[][] keyArray = new char[2][26];
for (int i = 0; i < 26; i++) {
keyArray[0][i] = (char) ('a' + i);
keyArray[1][i] = '*';
}
// restore keyArray original values if there is no solution to all words
if (!matchWords(words, eWordsCopy, keyArray))
for (int i = 0; i < 26; i++) {
keyArray[0][i] = (char) ('a' + i);
keyArray[1][i] = '*';
}
for (int i = 0; i < eWords.length; i++) {
StringBuilder temp = new StringBuilder();
for (int j = 0; j < eWords[i].length(); j++)
temp.append(keyArray[1][eWords[i].charAt(j) - 97]);
dWords[i] = temp.toString();
}
return dWords;
}
private static boolean matchWords(String[] words, String[] eWords, char[][] keyArray) {
ArrayList<String> promisingWords = new ArrayList<>();
String eWord = eWords[0];
// this is an array of booleans to check whether a letter got updated. This array is useful in the backtracking
// step where we remove a word from the keyArray
boolean[] updatePattern = new boolean[eWord.length()];
// get promising words that may match
for (String word : words)
if (word.length() == eWord.length()
&& wordPattern(word).equals(wordPattern(eWord)))
promisingWords.add(word);
for (String word : promisingWords) {
if (mapWord(eWord, word, keyArray, updatePattern)) {
if (eWords.length > 1) {
// recursive call:
if (matchWords(words, Arrays.copyOfRange(eWords, 1, eWords.length), keyArray))
return true;
else {
// remove the word from the dictionary to try another one
for (int i = 0; i < eWord.length(); i++)
if (keyArray[1][eWord.charAt(i) - 97] == word.charAt(i) && updatePattern[i])
keyArray[1][eWord.charAt(i) - 97] = '*';
}
}
// if there are now decrypted words, then return true
else
return true;
}
}
// if there is no word mapped, then return false
return false;
}
private static boolean mapWord(String eWord, String word, char[][] keyArray, boolean[] updatePattern) {
// check one-to-one from the decrypted word to the dictionary word:
for (int i = 0; i < eWord.length(); i++)
if (keyArray[1][eWord.charAt(i) - 97] != word.charAt(i)
&& keyArray[1][eWord.charAt(i) - 97] != '*')
return false;
// check the other way around
for(int i=0; i<word.length(); i++)
if(!isLetterMapped(eWord.charAt(i), word.charAt(i), keyArray))
return false;
// update the key array:
for(int i=0; i<eWord.length(); i++) {
if (keyArray[1][eWord.charAt(i) - 97] == word.charAt(i))
updatePattern[i] = false;
else {
keyArray[1][eWord.charAt(i) - 97] = word.charAt(i);
updatePattern[i] = true;
}
}
// System.out.println("eWord: " + eWord);
// System.out.println("word: " + word);
// System.out.println("this mapping is: " + isMapped);
// if (isMapped)
// for (char[] aKeyArray : keyArray) System.out.println(Arrays.toString(aKeyArray));
return true;
}
private static boolean isLetterMapped(char eLetter, char letter, char[][] keyArray) {
for (int i = 0; i < 26; i++)
if (keyArray[1][i] == letter && keyArray[0][i] != eLetter)
return false;
return true;
}
// generate a word pattern
private static String wordPattern(String word) {
if (word.length() > 0) {
StringBuilder mapped = new StringBuilder();
int count = 0;
HashMap<Character, Character> mapping = new HashMap<>();
for (int i = 0; i < word.length(); i++)
if (!mapping.containsKey(word.charAt(i)))
mapping.put(word.charAt(i), (char) (48 + count++));
for (int i = 0; i < word.length(); i++)
mapped.append(mapping.get(word.charAt(i)));
return mapped.toString();
} else {
return "";
}
}
}