Problem: http://www.codechef.com/problems/LEBOMBS
I have tried every single test case that come to my mind. But it still gives a wrong answer. I don't know why.
Please point out if there's any error in my code. This is my code.
#include <iostream>
using namespace std;
int main() {
int t, i, total, n;
char a[1001];
cin >> t;
while (t--) {
i = 0;
cin >> n;
total = n;
cin >> a;
while (i < n) {
if (a[i] == '1') {
if (i == '0')
total -= 2;
else if (i == 1) {
if (a[i - 1] == '1')
total--;
else
total -= 3;
} else if (i > 1 && i < n - 1) {
if (a[i - 1] == '1')
total--;
else if (a[i - 2] == '1')
total -= 2;
else
total -= 3;
} else {
if (a[i - 1] == '1')
;
else if (a[i - 2] == '1')
total--;
else
total -= 2;
}
}
i++;
}
if (total < 0)
total = 0;
cout << total << "\n";
}
return 0;
}
P.S. If you see the code, there is a line that says "if(total<0)total=0;" that is for the case when the number of buildings is equal to 1 or 2, because that case gave the wrong answer for the code that I wrote, but after that it gives a wrong answer. Please help.
And is there any way about how do I think a test case that might be violating my code for future reference?
Your method is really complicated, and I'm not sure why it is that way:
bool bombs_nearby(char *bombs, int length, int index) {
if (length == 1)
return bombs[0] == '1';
if (index == 0)
return bombs[0] == '1' || bombs[1] == '1';
if (index == length - 1)
return bombs[length - 1] == '1' || bombs[length - 2] == '1';
return bombs[index - 1] == '1' || bombs[index] == '1' || bombs[index + 1] == '1';
}
int remaining_buildings(char *bombs, int length) {
int total = 0;
for (int i=0; i<length; ++i)
if (!bombs_nearby(bombs, length, i))
total++;
return total;
}
And the test case code would just be:
cin >> n >> a;
cout << remaining_buildings(a, n) << "\n";
Test Cases
Additionally, here's a test case that you fail:
1 49 0101100010101110000101111101101010011010001100111
The correct answer is 4, but you only claim 2 houses will survive.
Why does your code fail that test case?
So, I spent some time re-reading your code. And it's actually not that bad of a method. I think if there was a comment describing what you were trying to do, it would have been very clear how you were going about it.
Sadly though, all of your pain is due to a very small bug:
while (i < n) {
if (a[i] == '1') {
if (i == '0')
total -= 2;
Note that you test i == '0'. You meant to do i == 0. You should be testing that you are not at the zeroth index, not that i is the '0' character.
Related
Hi is there way to check that your code is Recursion or not in c++? I write code but someone tell me that it isn't Recursion. I want to make sure.
#include <iostream>
#include <conio.h>
using namespace std;
bool winding(string str, int len) {
int counttrue = 0;
for(int i = 0; i < len; i++){
if(str[i] == '1') counttrue++;
else if(i != len - 1 && str[i] == '0' && str[i + 1] == '0') {
counttrue += 2; i++;
}
}
return (counttrue == len);
}
int main() {
string strwinding;
cin >> strwinding;
cout << winding(strwinding, strwinding.length()) << endl;
cout << "Continue...";
getch();
return 0;
}
A recursive function calls itself, and yours doesn't, so it's not recursive.
Assuming that the definition of a "winding" string is
The empty string, or
A 1 followed by a "winding" string, or
00 followed by a "winding" string,
a straightforward translation could look like this:
bool winding(const string& str, int index)
{
return index >= str.size()
|| ((str[index] == '1') && winding(str, index+1))
|| ((index < str.size() - 1)
&& str[index] == '0'
&& str[index+1] == '0'
&& winding(str, index+2));
}
// ...
cout << winding(strwinding, 0) << endl;
A recursive function is a function that calls itself, like for instance:
int fac(int x)
{
if (x <= 1) return 1; else return x * fac(x - 1);
}
You can easily check if a function is recursive if you create a breakpoint at the beginning of the function and see if this breakpoint is reached more than once if you call the function from outside once.
I have a question about 935B - Fafa and the Gates in CodeForces. My code is working for the first test cases but it’s getting stuck on test case 20, this is the code I used, could someone please tell me what I’m doing wrong here? Thanks!
#include <iostream>
#include <string>
using namespace std;
int main(){
long long a, x = 0, y = 0, total = 0;
cin >> a;
string s;
cin >> s;
for (long long i = 0; i <= a; i++){
if (s[i] == 'U') x += 1;
if (s[i] == 'R') y += 1;
if (x == y && s[i] == s[i+1]) total += 1;
}
cout << total << endl;
}
Aside from the i<=a issue I called out in the comments above, there's another issue.
Even if you fix the for loop to be stop after i<a, then this statement:
if (x == y && s[i] == s[i+1]) total += 1;
Will still reference an invalid index at s[i+1] since i+1 is an invalid index on the last iteration of the array.
On each iteration of the loop, you need to see if he's at the gate first, then update x or y appropriately, then assess if he changed kingdoms.
If he's at a position x > y, you know he's in the lower kingdom. Likewise if y > x, you know he's in the upper kingdom on the map.
I think this is closer to what you want:
bool topKingdom = false; // initially at 0,0. Fafa is currently in the "lower kingdom" on the map
for (long long i = 0; i < a; i++){
bool atGate = (x == y);
if (s[i] == 'U') y++;
if (s[i] == 'R') x++;
// if we were previously "at a gate", assess if we are now in a new kingdom from before
if (atGate && !topKingdom && y > x) {
topKingdom = true;
total++;
}
else if (atGate && topKingdom && x > y) {
topKingdom = false;
total++;
}
}
cout << total << endl;
Recently I've been working on this problem on SPOJ:
Given a set of N integers A = {1, 2, 3, …, N} and an integer S, your task is find a way to insert an operator '+' or '-' to every neighbor pair of A, that the result of the expression after insert equal to S.
WARNING: You can't put any operators in front of 1.
Input:
A single line, including N and S (1 ≤ N ≤ 500, |S| ≤ 125250)
Output:
If there are way(s) to insert, output any of them, otherwise output “Impossible” (without quotes).
Example:
Input:
9 5
Output:
1-2+3-4+5-6+7-8+9
Input:
5 6
Output:
Impossible
I've already been messing up with these code, but SPOJ always yields that I've done this problem in the wrong way. I think there might be exceptions that I haven't found out.
int main()
{
int n;
cin >> n;
int a[501] = { };
int sum = 0;
for (int i = 1; i <= n; i++)
{
a[i] = 1;
sum += i;
}
int s;
cin >> s;
int aim = sum - s;
if ((aim % 2 != 0) || (s < -sum + 2) || (s > sum) || (s == -sum + 4) || (s == sum - 1))
{
cout << "Impossible" << endl;
return 0;
}
int c = n;
while (aim != 0)
{
if (aim >= c)
{
if (aim - 2 * c != 2)
{
aim -= (2 * c);
a[c] = -1;
c--;
}
else
{
a[c - 1] = -1;
a[2] = -1;
aim -= (2 * c + 2);
}
}
else
{
a[aim / 2] = -1;
aim = 0;
}
}
for (int i = 1; i <= n; i++)
if (a[i] == 1)
if (i == 1)
cout << i;
else
cout << "+" << i;
else
cout << "-" << i;
return 0;
}
You are subtracting 2 * c from aim after checking if aim >= c.
Changing the check to aim >= 2 * c will improve your program.
This program is a part of an exam I just took, that I had to write. I only got this far and couldn't get anywhere. Here is the prompt:"Write a Test Function toDecimal() that converts a roman numeral such as MMLXVII to it's decimal number representation. Use Main() to test the function. The toDecimal() function should have 2 arguments, the string array of roman numerals and a helper function. This helper function will return the numeric value of each of the letters used in roman numbers. Then convert the string arguments as so: Look at the first two characters,if the first is larger, convert the first and add it to the summation, then call the conversion function again with the second value and add both. IF the first character is lesser than the second subtract the first from the second, and add the result to the conversion of the string. without validation it will also convert strings like "IC". VAlidate the string arguement, if there is an error, call the error processing function. Provide at least two error processing functions and test toDecimal() with each. One could be adking the user to correct, the other may correct it."
I,X,C,M cannot be repeated more than 3 times in succession, D,L,V, can never be repeated in succession.I can only be subtracted from V and X,X can only be subtracted from L and C, C can only be subtracted from D and M. V, L, and D can never be subtracted.
I've lost about 2 days worth of sleep on this, tried writing it hundreds of different ways using and breaking the rules. This is the closest I've got on it.
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cstring>
using namespace std;
bool checker(string roman);
// Adds each value of the roman numeral together
int toDecimal(string, bool* (*function)(string));
int convert(string roman, int i);
int main(){
string roman;
cout << "This program takes a roman numeral the user enters then converts it to decimal notation." << endl;
cout << "Enter a roman numeral: ";
cin >> roman;
transform(roman.begin(), roman.end(), roman.begin(), toupper);
cout << roman << " is equal to " << toDecimal(roman, *checker(roman)) << endl;
}
bool checker(string roman){
int length = roman.length();
for (int count = 0; count < length; count++){
string sub = roman.substr(count, count);
if(sub != "I" || sub != "V" || sub != "X" || sub != "L" || sub != "C" || sub != "D" || sub != "M"){
cout << "Error. Try Again"<< endl;
return false;
}
else if(convert(roman, count) == convert(roman, count-1) && convert(roman, count) == convert(roman, count+1)){
if (convert(roman,count) == 1 || convert(roman,count) == 10 || convert(roman,count) == 100 || convert(roman,count) == 1000)
if(convert(roman, count-1) == convert(roman, count-2) || convert(roman, count+1) == convert(roman, count+2)){
cout << "Error Try again" << endl;
return false;
}
else if (convert(roman,count) == 5 || convert(roman,count) == 50 || convert(roman,count) == 500){
cout << "Error Try again" << endl;
return false;
}
else return true;
}
}
return true;
}
int toDecimal(string s, bool*(checker) (string roman)){
/**map<char, int> roman;
roman['M'] = 1000;
roman['D'] = 500;
roman['C'] = 100;
roman['L'] = 50;
roman['X'] = 10;
roman['V'] = 5;
roman['I'] = 1;*/
checker(s);
int res = 0;
for (int i = 0; i < s.length() - 1; ++i){
int num = convert(s,i);
res += num;
/**if (roman[s[i]] < roman[s[i+1]])
res -= roman[s[i]];
else
res += roman[s[i]];
}
res += roman[s[s.size()-1]];*/}
return res;
}
int convert(string roman, int i){
enum romans {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};
int num = 0;
char c = roman[0];
switch(c){
case 'M':
num = M; break;
case 'D':
if(i + 1 != roman.size() && roman[i+1] == 'M'){
num = M - D;break;
}
else
num = D; break;
case 'C':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D'){
if(roman[i+1] == 'M') num = M - C; break;
if(roman[i+1] == 'D') num = D - C; break;
}
else
num = C; break;
case 'L':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'){
if(roman[i+1] == 'M') num = M - L; break;
if(roman[i+1] == 'D') num = D - L; break;
if(roman[i+1] == 'C') num = C - L; break;
}
else
num = L; break;
case 'X':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L'){
if(roman[i+1] == 'M') num = M - X; break;
if(roman[i+1] == 'D') num = D - X; break;
if(roman[i+1] == 'C') num = C - X; break;
if(roman[i+1] == 'L') num = C - X; break;
}
num = X; break;
case 'V':
if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L' || roman[i+1] == 'X'){
if(roman[i+1] == 'M') num = M - V; break;
if(roman[i+1] == 'D') num = D - V; break;
if(roman[i+1] == 'C') num = C - V; break;
if(roman[i+1] == 'L') num = L - V; break;
if(roman[i+1] == 'X') num = X - V; break;
}
num = V; break;
case 'I':
if ( i + 1 != roman.size() && roman[i + 1] != 'I'){
if(roman[i+1] == 'M') num = M - I; break;
if(roman[i+1] == 'D') num = D - I; break;
if(roman[i+1] == 'C') num = C - I; break;
if(roman[i+1] == 'L') num = L - I; break;
if(roman[i+1] == 'X') num = X - I; break;
}
num =1; break;
}
return num;
}
** I have added the help of people on here. This is an edit to show an progress/congress.
This is the code that I use to convert Roman (smaller than 3999) to Integer. You may check if it works for larger numbers.
int romanToInt(string s) {
map<char, int> roman;
roman['M'] = 1000;
roman['D'] = 500;
roman['C'] = 100;
roman['L'] = 50;
roman['X'] = 10;
roman['V'] = 5;
roman['I'] = 1;
int res = 0;
for (int i = 0; i < s.size() - 1; ++i)
{
if (roman[s[i]] < roman[s[i+1]])
res -= roman[s[i]];
else
res += roman[s[i]];
}
res += roman[s[s.size()-1]];
return res;
}
Hope this could help you.
The solution provided by Annie Kim works, but it uses a std::map, querying it several times for the same character, and I fail to see a reason for it.
int convert_roman_digit(char d)
{
switch (d)
{
case 'M': return 1000;
case 'D': return 500;
case 'C': return 100;
case 'L': return 50;
case 'X': return 10;
case 'V': return 5;
case 'I': return 1;
default: throw std::invalid_argument("Invalid digit");
}
}
int roman_to_int(const std::string& roman)
{
int result = 0, last_added = 0;
for (auto it = roman.rbegin(); it != roman.rend(); ++it)
{
const int value = convert_roman_digit(*it);
if (value >= last_added)
{
result += value;
last_added = value;
}
else
{
result -= value;
}
}
return result;
}
Caveat: the function happily accepts some invalid inputs (e.g. IMM) including "negative" numbers (e.g. IIIIIIIIIIIIIX), there are no overflow checks, and it throws. Feel free to improve it.
int romanToInt(string s)
{
unordered_map<char, int> roman;
roman['I'] = 1;
roman['V'] = 5;
roman['X'] = 10;
roman['L'] = 50;
roman['C'] = 100;
roman['D'] = 500;
roman['M'] = 1000;
int num = 0, prev = 0, curr;
for (int i = s.length() - 1; i >= 0; i--)
{
curr = roman[s[i]];
num += (curr >= prev ? 1 : -1) * curr;
prev = curr;
}
return num;
}
Assignment is to Complete the 8 queens 2 dimensional array program with backtracking.
#include <iostream>
using namespace std;
int main() {
int b[8][8] = { 0 };
int r, c, i;
int count = 1;
b[0][0] = 1;
c = 0;
nextColumn:
c++;
if (c == 8)
goto print;
r =- 1;
nextRow:
r++;
if (r == 8)
goto back;
for (i = 0; i < c; i++) {
if (b[r][i] == 1)
goto nextRow;
}
for (i = 0; (r - i) >= 0 && (c - i) >= 0; i++) {
if (b[r - i][c - i] == 1)
goto nextRow;
}
for (i = 0; (r + i) < 8 && (c - i) >= 0; i++) {
if (b[r + i][c - i] == 1)
goto nextRow;
}
b[r][c] = 1;
goto nextColumn;
c--;
if (c == -1)
return 0;
r = 0;
while (b[r][c] != 1)
r++;
b[r][c] = 0;
goto nextRow;
cout << endl;
cout << "Result No." << count << endl;
cout << endl;
for (r = 0; r < 8; r++){
for (int c = 0; c < 8; c++){
cout << b [r][c];
}
cout << endl;
}
count++;
goto back;
}
Well, no.
Everything is one big function; it should be broken in to little functions
The program -- like all programs -- should be self-testing. There should be a function that returns true if the program worked and false if it didn't.
You're using single-character variable names; variables should have meaningful names.
You're writing to cout at every level; you should be performing calculations, returning results, then (optionally) printing results to cout.
You're using goto, which is generally ConsideredHarmful. And you're using it a lot, which is always ConsideredHarmful.
If you care about your program being correct, make sure it's readable first.
So properly indent the program, declare (and init) variables where you use them, and stop using the goto statement. There's break if you want to bail out early from a for loop. (Or better, write the loop code in a separate function and use early returns!).