Similar solutions but different answers - c++

I am facing difficulty while solving a problem where we have to check whether a string is a subsequence of another string or not.
A man with name M is allowed to marry a woman with name W, only if M is a subsequence of W or W is a subsequence of M.
A is said to be a subsequence of B if A can be obtained by deleting some elements of B without changing the order of the remaining elements.
Example -
john and johanna will give "YES" as output
kayla and jayla will give "NO" as output
johanna and john will give "YES" as output
My code is :
#include <iostream>
#include<string>
using namespace std;
bool checksub(string a, string b)
{
int pos=0;
for(int i=0; i<a.size(); i++)
{
int flag=0;
for(int j=pos; j<b.size(); j++)
{
if(b[j]==a[i])
{
flag=1;
pos=j;
break;
}
}
if(flag==0)
{
return false;
}
}
return true;
}
int main() {
// your code goes here
int t;
cin>>t;
while(t--)
{
string a,b;
cin>>a>>b;
if(a.size()==b.size())
{
if(a==b)
{
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;}
}
else if(a.size()>b.size()){
if(checksub(b,a))
{
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}else{
if(checksub(a,b))
{
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
}
return 0;
}
The editorial of the question uses a similar approach. Can anybody tell me what's wrong with my code?
The editorial solution is given below :
#include <cstdio>
char M[25005], W[25005];
bool contains(const char *A, const char *B){
while(*A){
if(*B==*A)
B++;
A++;
}
return !*B;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%s %s", M, W);
puts(contains(M, W) || contains(W, M) ? "YES" : "NO");
}
return 0;
}
Link to the problem: https://www.codechef.com/problems/NAME2

Your code produces the wrong result with input AA BAB because it fails to account for the fact that you need to have two A in the second string.
You might be able to fix it by changing pos=j; to pos=j+1; but I'm not certain.
There really is no similarity between your code and the editoral code however. Even with my suggested fix (if it does work) your code is clearly less efficient than the editorial code because it scans the input strings repeatedly.

Got the correct answer just by changing pos=j+1 instead of pos=j. Then code will become similar to the pseudocode in the editorial. Thanks, everybody for answering.

Related

C++: Error in login, identify a valid triangle with greater greater then 0, all three angles provided

I have written this program, it passes all manual test conditions but says "wrong answer" when I submit online on an IDE.
Constraints
0≤a,b,c≤180
#include <iostream>
using namespace std;
int main() {
// your code goes here
double a,b,c;
cin>>a>>b>>c;
if(a+b+c==180)
cout<<"YES";
else
cout<<"NO";
return 0;
}
The above code doesn't give correct answer when either of a,bc is zero and the a+b+c=180.
So,
int main()
{
// your code goes here
double a,b,c;
cin>>a>>b>>c;
//add the below statement
if((a!=0)&&(b!=0)&&(c!=0)){
if(a+b+c==180)
cout<<"YES";
else
cout<<"NO";
}
else{
cout<<"NO";
}
return 0;
}
int main()
{
// your code goes here
double a,b,c;
cin>>a>>b>>c;
//made the changes with the help of suggestion from the forum
if((a>0)&&(b>0)&&(c>0)&&(a+b+c==180))
cout<<"YES";
else
cout<<"NO";
return 0;
}

Getting wrong answer in a DP problem although implementation looks correct

I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}

Why am I getting a WA in Faded Palindromes in Codechef even though I found no error till now in my code and its working fine for me?

I have been debugging and seeing this code for nearly a week now still I couldn't find any solution and thus hoping to get one from the fellow developers in stack overflow.
This is the solution of the Faded Palindrome problem of September Challenge Codechef This is the problem page
#include<iostream>
#include<vector>
#include<iterator>
#include<stdlib.h>
#include<cstdio>
#include<string>
using namespace std;
string def="-1";
int main()
{
int t;
cin>>t;
//vector<string> out(t);
string out[100];
for(int i=0;i<t;i++)
{
string inp;
cin>>inp;
if(inp.size()%2) //Checking wether the number of letters is odd
{
int counter=inp.size()/2;
int counter_back=counter-1;
int counter_front=counter+1;
if(inp[counter]=='.')
inp[counter]='a';
int not_fa=0;
while(counter_back>=0&&counter_front<inp.size())
{
if(inp[counter_back]==inp[counter_front])
{counter_back--;counter_front++;}
else if(inp[counter_back]=='.'&&inp[counter_front=='.']){
inp[counter_back]=inp[counter_front]='a';
counter_back--;counter_front++;
}
else if(inp[counter_back]=='.'){
inp[counter_back]=inp[counter_front];
counter_back--;counter_front++;
}
else if(inp[counter_front]=='.'){
inp[counter_front]=inp[counter_back];
counter_back--;counter_front++;
}
else{
not_fa=1;
break;
}
}
if(not_fa)
out[i]=def;
else
out[i]=inp;
}
else{ //Checking the number of letter is even
//cout<<inp.size();
int counter_front=(inp.size())/2;
//cout<<counter_front;
int counter_back=counter_front-1;
//cout<<counter_back;
int not_fa=0;
while(counter_back>=0&&counter_front<inp.size())
{
if(inp[counter_back]==inp[counter_front])
{//cout<<"*-";
counter_back--;counter_front++;}
else if(inp[counter_back]=='.'&&inp[counter_front]=='.'){
inp[counter_back]=inp[counter_front]='a';
counter_back--;counter_front++;
}
else if(inp[counter_back]=='.'){
//cout<<"--";
inp[counter_back]=inp[counter_front];
counter_back--;counter_front++;
}
else if(inp[counter_front]=='.'){
inp[counter_front]=inp[counter_back];
counter_back--;counter_front++;
}
else{
not_fa=1;
break;
}
}
if(not_fa)
out[i]=def;
else
out[i]=inp;
}
}
/*vector<string>::iterator itr;
for(itr=out.begin();itr!=out.end();itr++)
cout<<*itr<<endl;*/
for(int j=0;j<t;j++)
if(j==t-1)
cout<<out[j];
else
cout<<out[j]<<"\n";
return 0;
}
While your code may pass all the test cases presented in the problem statement, there are still more edge cases that your code doesn't cover. Here's a sample test case:
6
..
...
..e
a..a.v.
p..p
t.xzt
This should print:
aa
aaa
eae
avaaava
paap
tzxzt
instead it prints:
..
.a.
aaa
aa.a.aa
p..p
taxat
Hints:
The first if statement is not correctly handling the case where inp[b] and inp[f] are both '.'.
There is no need for doing two different things when |s| is even or odd.
Also, in the first else if statement, you probably meant inp[counter_front]=='.' instead of inp[counter_front=='.'].
if(inp[counter_back]==inp[counter_front]) is true if they both are equal to '.' so you won't fill that gap.

SPOJ: What is the difference between these two answers for KURUK14

I have solved this problem and got AC. My problem is related to equivalence of following two approaches. The first code got accepted, while the second didn't.
As far as I can discern, both are completely equivalent for all the (valid) test cases any human can think of. Am I wrong? If so, what test case can differentiate them?
Code#1 (Accepted one):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
}
bool f = true;
for(int k=0;k<N;k++)
{
f = f && M[k];
}
return f;
}
int main() {
M=new bool[1002];
int num=0;
scanf("%d",&num);
while(num){
int N=0;
scanf("%d",&N);
if(proc(N))
printf("YES\n");
else
printf("NO\n");
num--;
}
return 0;
}
Code #2 (WA):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
else
return false;
}
return true;
}
int main() {
//Exactly same as code#1
}
The bug has nothing to do with the algorithm itself—it's very possible both the algorithms are correct. But the second implementation is wrong.
When you reach a test case which should return NO, you exit the function prematurely. Which means there are some numbers from the current test case left unread in the input, which of course confuses further reading thoroughly. This means the bug only manifests when T > 1.

Incorrect outputs for simple solution

Codeforces problem 373A-http://codeforces.com/problemset/problem/373/A
Instead of multiple if statements for counting number of elements of each number,I have tried to check for given condition after sorting the array.I am getting incorrect output for 1st test case(given in the link for the problem).What is wrong with my approach?What should I change in my solution.
My solution:
#include<iostream>
#include<cstring>
using namespace std;
int k,i,j,a;
char panel[17],temp,output[4];
int main()
{
cin>>k;
for(i=0;i<16;i++)
cin>>panel[i];
for(i=0;i<16;i++) //Bubble sort.
{
for(j=0;j<(15-i);j++)
{
if(panel[j]>panel[j+1])
{
temp=panel[j+1];
panel[j+1]=panel[j];
panel[j]=temp;
}
}
}
a=1;
strcpy(output,"YES");
for(i=0;i<16;i++)
{
if(panel[i]==panel[i+1])
++a;
else
a=1;
if(a>(2*k));
{
strcpy(output,"NO");
break;
}
}
cout<<output;
}
You have a semi-colon after the if statement:
if(a>(2*k));
That means, it's always going copy "NO" and break the loop. Remove it.