Here is the link to the question: http://www.spoj.com/problems/SMPSEQ3/
I am getting WA every time although the code works for all of the test cases I have tried
Please give me a hint.I am a beginner in this
This is my code.
#include<iostream>
using namespace std;
int main()
{
int n, m;
bool check;
int cnt=0;
cin >> n;
int s[n];
int c[n];
for(int i = 0; i < n; i++)
cin >> s[i];
cin >> m;
int q[m];
for(int i = 0; i < m; i++)
cin >> q[i];
for(int i = 0; i < n; i++)
{
check = false;
int j = 0;
while(q[j] <= s[i])
{
if(q[j] == s[i])
check = true;
j++;
}
if(check == false)
{
c[cnt] = s[i];
cnt++;
}
}
for(int i = 0; i < cnt; i++)
cout << c[i] << " ";
return 0;
}
You code fails because you do not keep a check on the value of j whether it is less than m or not, you simply keep on incrementing it until you hit a value where q[j] <= s[i]. So, when your j becomes m in the while loop, you are actually accessing memory which was not allocated to you, and there is some garbage value stored there. Since the garbage value can be anything you might eventually miss some values in q[] which should be added to c[].
So, your while condition shall look like this ::
while(j < m && q[j] <= s[i])
I think this shall give you an AC.
A few more things you initialize j = 0 every time you enter the for loop, which is useless. Since in the question it is given that both the sequences are sorted, so considering the sequences ::
S = a, b, c, d . . .
Q = aa, bb, cc, dd . . .
So, considering if aa < a but bb > a so, in the first iteration your j stops at bb. So, now when i comes at b in S, since a > aa and b >= a(S is a sorted sequence), so b > aa as well. So, you do not need to initialize j = 0 at the beginning of every iteration, which will save you wasteful computations. You just need to initialize j = 0 at beginning of the main.
Moreover, you do not need to save the result in a new array, you can simply print it, when you encounter check == false, this save you some space.
Related
I wrote a simple program to find the longest sub-string with distinct characters in a given string in C++. My code works for certain inputs, but doesn't for others. Moreover, it gives me different outputs for the same inputs. Where am I going wrong?
int main() {
int t;
cin >>t;
while(t--){
string s;
cin >> s;
int n = s.length();
int maxlen = 0;
for(int i = 0; i < n; i++){
int count = 0;
int arr[26] = {0};
bool isDist = true;
int j = i;
while(isDist){
if(arr[(int)s[j] - (int)'a'] == 0){
count++;
arr[(int)s[j] - (int)'a'] = 1;
j++;
} else {
isDist = false;
}
}
if(count > maxlen) maxlen = count;
}
cout << maxlen << endl;
}
return 0;
}
for the following input:
3
aewergrththy
aewergrththy
aewergrththy
My code outputs:
5
4
4
Any help is appreciated, Thank you!
The problem is that there is no check that j remains less than n, so you start checking characters beyond the end of your string, leading to in unpredictable results. Try
while (isDist && j < n)
That should help but I haven't checked the rest of your code for errors.
You could also consider using s.at(j) instead of s[j]. That at least results in predictable behaviour when going out of bounds, at throws an exception in that case.
The program has undefined behavior because you do not bounds-test when iterating over the string with j. You should modify the inner loop to test for j in addition to isDist:
while(isDist && j < n)
Without this, it's very easy for j to shoot past the end of the string as soon as all remaining characters in the string have not yet been encountered.
In this case, it will be when you process the character 'y' at the end of the string. After dealing with 'y', you'll advance j such that s[j] returns the string terminator. Now, you'll be accessing the array with arr[0 - 'y'] which of course is undefined behavior due to being a negative index.
so I made a simple loop that finds out if an array has the elements with the values of 0 and 1.
if the loop indeed finds 0 or 1 inside of the array, it will say "YES", otherwise "NO".
yes, the program works just fine, but at the end of the program it prints out "YES" or "NO" as many times as i put cin>>dim to.
for example if dim which means (dimension[of the array]) is 5 it's going to print either "YESYESYESYESYES" or "NONONONONO"
I have to use return 0 in order to make it print it out like once, but I feel like this is not the right way to do it. Please help me with this. thanks!
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i, dim, v[100];
cin>>dim;
for(i=0;i<dim;i++)
cin>>v[i];
for(i=0;i<dim;i++)
if(v[i]==0 || v[i]==1){
cout<<"YES"; return 0;}
else{
cout<<"NO"; return 0;}
return 0;
}
The break statement can be used to break out of loops. The example from cppreference:
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 5; k++) { //only this loop is affected by break
if (k == 2) break;
std::cout << j << k << " ";
}
}
As the comment suggests, break only breaks the innermost loop.
In your code you always exit from the loop on the very first iteration, hence you do not need the loop in the first place. This will have the same output as your code:
int main() {
int i, dim, v[100];
cin >> dim;
for(i=0; i < dim; i++)
cin >> v[i];
if(v[0] == 0 || v[0] == 1) {
cout << "YES";
} else {
cout << "NO";
}
}
After reading the question again...
I made a simple loop that finds out if an array has the elements with the values of 0 and 1
If you exit the loop after checking the first element then you only check the first element. If you want to see if an array contains only 1 or 0 or it contains at least one element which is 0 or 1 (not 100% clear which one you want), then you rather need this:
bool only_zero_or_one = true;
bool one_zero_or_one = false;
for (int i = 0; i < dim; ++i) {
zero_or_one = ( v[i] == 0 | v[i] == 1);
only_zero_or_one = zero_or_one && only_zero_or_one;
one_zero_or_one = zero_or_one || one_zero_or_one;
}
Only for one_zero_or_one you can break the loop once zero_or_one == true.
Moreover, you should rather use a std::vector. In your code, if the user enters a dim which is greater than 100 you write beyond the bounds of v. This can be avoided easily:
size_t dim;
std::cin >> dim;
// construct vector with dim elements
std::vector v(dim);
// read elements
for (size_t i=0; i < v.size(); ++i) std::cin >> v[i];
// .. or use range based for loop
for (auto& e : v) std::cin >> e;
but I feel like this is not the right way to do it
Returning is an entirely right way to break out from a loop.
Another right way is the break statement, which jumps to after the loop.
Even better, you can actually check if v[i]==0 or 1 inside the input for loop immediately after taking input and set a flag to true. Depending on requirement, you can either break or wait until the entire input is read and then come out and check for flag==true and then print "YES" and print "NO" if flag==false.
This will save you running the loop again to check for 0 or 1.
I'm writing a program in C++ and I have input with bounds and a grid for example:
4 4
SOUI
1234
WER5
0234
I'm using the following loop to read input
int N, M, startR = 0, startC = 0;
string matrix[105][105], instr;
cin >> N >> M;
for(int i = 0; i < N; i++){
cin >> instr;
for(int j = 0; j < M; j++){
matrix[i][j] = instr[j];
if(matrix[i][j] == "B"){
startR = i;
startC = j;
}
}
}
If I use this code, the program will ask for more input and won't run no matter what I give it. This means the code after this input loop is never used. However, if I remove the setting of variables, the program runs fine. For example:
int N, M, startR = 0, startC = 0;
string matrix[105][105], instr;
cin >> N >> M;
for(int i = 0; i < N; i++){
cin >> instr;
for(int j = 0; j < M; j++){
matrix[i][j] = instr[j];
}
}
I'm not sure why this is happening as all I'm doing is setting some other variables. I need the information about where the variable B is found. Any ideas why this is happening?
I solved this as the problem lied in the code after the loop. The problem was misleading as it seemed like cin was taking more input but it was actually the infinite loop later. I tried to first debug using print statements immediately after the cin statement to see what was being taken in but those weren't run which is what threw me off. My takeaway is to look at the program completely and use a full debugger.
One day, Twilight Sparkle is interested in how to sort a sequence of
integers a1, a2, ..., an in non-decreasing order. Being a young
unicorn, the only operation she can perform is a unit shift. That is,
she can move the last element of the sequence to its beginning:
a1, a2, ..., an → an, a1, a2, ..., an - 1. Help Twilight Sparkle to
calculate: what is the minimum number of operations that she needs to
sort the sequence?
Input
The first line contains an integer n (2 ≤ n ≤ 105). The second
line contains n integer numbers a1, a2, ..., an (1 ≤ ai ≤ 105).
Output
If it's impossible to sort the sequence output -1. Otherwise
output the minimum number of operations Twilight Sparkle needs to sort
it.
Examples
input
2
2 1
output
1
input
3
1 3 2
output
-1
input
2
1 2
output
0
Above is the problem and now I am confused because the solution down there used a variable called "s" and played around it for some reason but I don't know why was that variable used, if someone can tell me I'll be thankful.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, s, v(0);
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n - 1; i++) if (a[i] > a[i + 1]) s = i, v++;
if (a[n - 1] > a[0]) s = n - 1, v++;
if (v == 0) cout << 0 << endl;
else if (v > 1) cout << -1 << endl;
else cout << n - 1 - s << endl;
return 0;
}
Now here is my own solution, it works and everything except on a 10^5(and around that) size array but the question time limit is only 1000 ms, and mine exceeds that limit due to the nested loops making it go over O(10^8) which is 1000 ms on their systems.
#include <bits/stdc++.h>
#define fl(i,n) for(int i = 0; i < n; i++)
#define ll long long
#define nl endl
#define pb push_back
#define mp make_pair
#define PII pair<int,int>
#define EPS 1e-9
#define INF 1e9
using namespace std;
bool check(int a[], int n){
for(int i = 0; i < n-1; i++){
if(a[i] <= a[i+1]) continue;
return false;
}
return true;
}
int main()
{
int n;
cin >> n;
int a[n]; //is out of standard i know but it's accepted in the contest's compiler so we just use it
for(int i = 0; i < n; i++){
cin >> a[i];
}
if(check(a,n)){
cout << 0;
return 0;
}
int ret = 0;
for(int i = 0; i < n-1; i++){
ret++;
for(int j = n-1; j > 0; j--)
a[j] ^= a[j-1] ^= a[j] ^= a[j-1]; //is xor swap
if(check(a,n)){
cout << ret;
return 0;
}
}
cout << -1;
return 0;
}
PS: I TRACED the solution's code and even if I get the correct answers I simply don't know what it refers to.
The other person's implementation relies on an algorithmic insight. The only way a sequence can be sorted by moving back to front is if the sequence is made of two already-sorted sections. Then, the goal is to check how many unsorted discontinuities exist, and where they are. That's what s appears to be used for: the index of the (last) discontinuity of the sequence. v is the count of discontinuities.
If there are 0, it's already sorted. If more than 1, it's unsortable. If it's exactly one, then you can easily figure out how many shifts you need to perform to pull the discontinuity back to the front, using it's location (s) in the original sequence.
The only extra line of code is the special case of checking for the discontinuity around end of the sequence.
My recommendation: Generate a larger set of test sequences, and print v and s for each one.
Find the minimum number of characters needed to make S a palindrome.For instance, if S = "fft", the string should be changed to the string "tfft", adding only 1 character.
Now, I used the dp approach for solving this problem which is as follows:
Let the given input string be S[1.....L]. Then for any substring S[i....j] of the input string, we can find the minimum insertions as:
min_insertions(S[i+1 ...... j-1]) [if S[i] is equal to S[j]]
min(min_insertions(S[i+1......j]), min_insertions(S[i....j-1])) + 1
I coded this as follows:
#include <iostream>
using namespace std;
int dp[100][100];
int main (void)
{
int n,i,j;
char arr[100];
cin>>arr;
n = strlen(arr);
//cout<<"You entered the string as "<<arr<<"\n";
for (i = 0; i < n; i++ )
dp[i][0] = 0;
for ( i = 0; i < n; i++ )
{
for ( j = 0; j < n; j++ )
{
if (arr[i] == arr[j])
dp[i][j] = dp[i+1][j-1];
else
dp[i][j] = min(dp[i+1][j],dp[i][j-1])+1;
}
// cout<<dp[0][n-1];
}
cout<<dp[0][n-1]<<"\n";
return 0;
}
However, this gives a wrong value. Why is it happening? For example, if I enter the string as abc, it outputs 1. What's wrong with this? Is there anything wrong with my logic?
You are not filling your array dp in the right order. For instance dp[0][2] will ask for dp[1][2] which has not been computed yet.
So the logic should be to have an assigning loop of the form :
for (int i = 0; i <n; i++) {
for (int h = 0; h < n-i; h++) {
dp[i][i+h] = .. // your part
}
}
You also need to be more careful about the case where h = 0 above, where you don't want to call dp[i+1][i] or dp[i][i-1], and h=1, arr[i]=arr[i+1] where you don't want dp[i+1][i] getting called.