Is there a problem with my map construction? - c++

My code didn't report a bug. But when run in the online judge system, I was told that it couldn't get right answer for some special samples. I can't figure it out, so I turn to here for help.
Problem Description
Every girl likes shopping,so does dandelion.Now she finds the shop is increasing the price every day because the Spring Festival is coming .She is fond of a shop which is called "memory". Now she wants to know the rank of this shop's price after the change of everyday.
Input
One line contians a number n ( n<=10000),stands for the number of shops.
Then n lines ,each line contains a string (the length is short than 31 and only contains lowercase letters and capital letters.)stands for the name of the shop.
Then a line contians a number m (1<=m<=50),stands for the days .
Then m parts , every parts contians n lines , each line contians a number s and a string p ,stands for this day ,the shop p 's price has increased s.
Output
Contains m lines ,In the ith line print a number of the shop "memory" 's rank after the ith day. We define the rank as :If there are t shops' price is higher than the "memory" , than its rank is t+1.
Sample Input
3
memory
kfc
wind
2
49 memory
49 kfc
48 wind
80 kfc
85 wind
83 memory
Sample Output
1
2
Code:
#include<algorithm>
#include<iostream>
#include<map>
#include<cstdio>
using namespace std;
const int maxn = 10010;
int main(){
int n,m;
map<string ,int> dic ;
char names[maxn][32];
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%s",names[i]);
dic[names[i]] = 0;
}
scanf("%d",&m);
while(m--){
for(int i = 0;i<n;i++){
int temp;
scanf("%d",&temp);
char tp[32];
scanf("%s",tp);
dic[tp] += temp;
}
int ranking = 1;
for(int j = 0;j<n;j++){
if(dic[names[j]]>dic[names[0]]){
ranking++;
}
}
printf("%d\n",ranking);
}
return 0;
}
Although I don't have any problem with the sample, but it Can't pass black box test.

Related

Rapid Typing Coding Challenge

The question asks for total time that will be required to type a string on a keyboard, which is represented as two dimensional matrix of characters, with one finger.
input:
2 31
YLrJpXOygVUl6MqBIRFWuAKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
YE0
The first line contains n and m as input denoting dimensions of the keyboard matrix.
Next n lines contain m characters each denoting the character in the keyboard.
Next line will contain a string S
output:
3
Explanation:
The finger is initially at the first symbol of the keyboard so the time taken to press that key is 0. After that the new key is located at 1,1 so total time taken will be |1-0|+|1-0| i.e. 2 . Now the third key is located at position 1,2 so total time to move to that key will be |2-1|+|1-1| = 1 . So our answer is 3.
The string that's asked to print is in the last input line, YE0, consisting of letters from the above 2-D matrix.
The time calculation logic is:
If you are at cell (x1,y1) of the keyboard and now you want to press the key at (x2,y2) then the time taken will be |x1-x2| + |y1-y2|. You need to calculate the total time taken to type the complete string.
In case it is impossible to type the string you have to print -1.
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
unordered_map<char, pair<int, int>> map1;
for(int i=0;i<n;i++){
string s;
cin>>s;
for(int j=0;j<m;j++) {
map1.insert({s[j], make_pair(i,j)});
}
}
string key;
cin>>key;
long long total=0;
pair<int,int> sp;
for(int i=0;i<key.length();i++) {
if(map1.find(key[i])==map1.end()) {
total=-1;
break;
} else {
auto it = map1.find(key[i]);
if(i==0) sp=it->second;
pair<int,int> p = it->second;
total+=(abs(p.first-sp.first) + abs(p.second-sp.second));
sp=p;
}
}
cout<<total;
}
This solution is partially accepted and I am not able to figure out the edge cases for which its failing. Can somebody help me?
Here is one failing test case for free.
2 31
YLrJpXOygVUl6MqBIRFWuAKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
YE 0
Should be -1 because the blank is not in the key matrix.
It fails because you only read in the "word" until first whitespace.
Here is another one:
2 31
YLrJpXOygVUl6MqBIRFW AKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
Y E0
Shoudl not be -1, but is. Same problem, but with the matrix.
So what you need to do is change your input reading to include white space.
It's mentioned in the question that, "The finger is initially at the first symbol of the keyboard" so when you are parsing the key
In your code if(i==0) sp=it->second; should start from {0,0} to consider the movement from the first symbol of the keyboard to the first symbol of the key.

Why does long shows wrong output in finding second maximum of three integers?

I am a novice to CP and while I was doing this problem of finding the second maximum among three numbers I wrote this code which however works for int but doesn't work for long even though they are the same data types.
Input Format:
The first line contains the number of triples, N.
The next N lines which follow each have three space separated integers.
Input Used:
3
1 2 3
10 15 5
100 999 500
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >>n ;
while(n--){
long a,b,c,d;//if i change long to int output is correct
scanf("%i%i%i",&a,&b,&c);
d=min(max(a,b),max(a,c));
printf("%i\n",d);// outputs 1 \n 10 \n 100 \n(\n means new line)
}
return 0;
}
Perhaps because you're using the wrong specifier. %i is for ints, but %li is for longs.

Logic error in writing the number twice in a row (C++)

I have been trying to implement something in C++ but apparently, there's a syntax error.
The following code yields "1 3100" when 31 is entered as input :
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n; cin>>n;
long long j = floor((log10(n)));
long long nn = (n*((long long)pow(10,j+1)))+n;
cout<<j<<" "<<nn;
}
The following code yields "1 3130" for the same input, i.e, 31 :
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n; cin>>n;
long long j = floor((log10(n)));
long long nn = (n*(pow(10,j+1)))+n;
cout<<j<<" "<<nn;
}
And I wished to produced "1 3131" for the input 31. Basically, I am trying to write the number twice in a row: the same thing that you get when you parse the number into string and add the same string twice (like, n=11, parse into s = "11" and then yield s+s).
So I want to multiply the input by a suitable power of ten to get enough "trailing zeros" and then add the input again.
Where am I going wrong? Also, why is there a difference between the two codes above? (Please explain why the first code gives that as an output and the second code that as an output and also help me with a newer code to get the desired output).
There is no syntax error, otherwise your code would not end up in an executeable to run.
The explanation for the unexpected output of "3130" is a misuse of a floating point function in an integer context.
long long n; cin>>n; // n becomes 31
long long j = floor((log10(n))); // j becomes 1
long long nn = (n*(pow(10,j+1)))+n; // the result from pow is a floating point just below 100
// integer-multiplied by 31 gives 3099
// adding 31 results in 3130
cout<<j<<" "<<nn; // output 3130

Need Help in a Project of C++

So this is the actual Problem
Can anyone tell me that how I read the repective Data from the file, and how would I able to store it in variables (without using array) also the code should be generic, That if the number of series will incresed or decresed.. Code will not be affected... I Just can't understand that how would I store sata in variables and how.. Please Help.. :(
Problem
A file contains information of a batsman. Information is no of series
played by the batsman. No of matches played in each series & score in
each match by the batsman. You have to read the data (without using
any array) and find average score and maximum score in all matches of
a series. In the end find overall average score and max score in all
matches.
Input:
Read data from file "cricket.txt". First line contains no of seasons/
series played by the player. Next pair of lines contains matches
played by the batsman followed in next line scores by batsman in
different matches of a season. See sample "cricket.txt"
5
6
93 75 41 40 90 19
5
45 86 30 60 29
3
47 90 33
4
22 2 92 5
5
88 67 96 91 90
First 5 shows player has played 5 seasons/ series
Next 6 show in first series player has played 6 matches
Next line has scores of player in 6 matches
Next 5 show in second series player has played 5 matches
Next line has scores of player in 5 matches
So on in second last line 5 shows player has played 5 matches in 5th
series
Last line has scores of player in 5 matches of last series
You're looking for an array.
int a[10];
// Loop that assigns all elements in array a to 0
for (int i = 0; i < 10; i++)
{
a[i] = 0;
}
// Array b will have all of it's members initialized to 0
int b[10]{};
// You can also assign different values to different elements of the array
b[0] = 6;
b[8] = 2;
// You can then use the array elements in operations
int c = b[0] * b[8];
If you want array like structure without compile time defined size, then use std::vector.
// An empty vector of ints
std::vector<int> d;
// A simple int
int e = 5;
// Push 2 values to the end of the vector
d.push_back(2);
d.push_back(e);
// Use the members for operations
int f = d.at(0) * d.at(1);
Since you've now described the problem you're trying to solve instead of just the problem with the solution you came up with:
You don't need to invent variable names or use arrays to compute averages and maximums.
Here's an example of how you can compute an average of the numbers a user inputs:
float sum = 0;
int elements = 0;
float input = 0;
while (cin >> input)
{
sum += input;
elements += 1;
}
std::cout << "Average: " << sum / elements << std::endl;
It's easy to expand this to also keep track of the maximum value so far.
To expand to the average and maximum of a number of series, add another loop "around" it.

SIGSEGV Error on Dynamic Programming - CodeChef

Hope you all are having a great day!
I love programming, but these past days I am having sleepless nights, with CodeChef always returning SIGSEGV errors on my Dynamic Programming solutions.
I am solving this question right now. Here's the question -
In Byteland they have a very strange monetary system. Each Bytelandian
gold coin has an integer number written on it. A coin n can be
exchanged in a bank into three coins: n/2, n/3 and n/4. But these
numbers are all rounded down (the banks have to make a profit). You
can also sell Bytelandian coins for American dollars. The exchange
rate is 1:1. But you can not buy Bytelandian coins. You have one gold
coin. What is the maximum amount of American dollars you can get for
it?
Input
The input will contain several test cases (not more than 10). Each
testcase is a single line with a number n, 0 <= n <= 1 000 000 000. It
is the number written on your coin. Output
For each test case output a single line, containing the maximum amount
of American dollars you can make. Example
Input: 12 2
Output: 13 2 You can change 12 into 6, 4 and 3, and then change these
into $6+$4+$3 = $13. If you try changing the coin 2 into 3 smaller
coins, you will get 1, 0 and 0, and later you can get no more than $1
out of them. It is better just to change the 2 coin directly into $2.
Now I know that it's very easy. And I did get stuck initially when I was declaring a big 10^9 integer long array (Over 1GB of memory..whoo!), but coming back to my senses - I decided to do memoization till 10001, and after that simple recursion. But still - I am making a mistake, and it's giving SIGSEGV error.
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
long long n[100001];
long long calc(long long x) {
if (x < 10001) {
if(n[x] != 0) return n[x];
n[x] = max(x, calc(x/2) + calc(x/3) + calc(x/4));
return n[x];
}
else return max(x, calc(x/2) + calc(x/3) + calc(x/4));
}
int main() {
memset(n, 0, sizeof(n));
n[1] = 1;
n[2] = 2;
n[3] = 3;
n[4] = 4;
n[5] = 5;
n[6] = 6;
for (int i = 7; i < 10001; i++)
n[i] = calc(i);
int t = 10;
while (t--) {
long long c;
scanf("%lld", &c);
printf("%lld\n", calc(c));
}
return 0;
}
I have solved some previous questions too - and all of them gave me this error once or twice. I know this error means that I am trying to access memory that hasn't been allocated, but what is wrong in my approach that I always get this error?
The problem is with the corner case n=0.
calc(0) recurses indefinitely because 0<10001 and n[0]=0. You need to add the terminating condition that calc(0)=0.
Takeaways:
Always check your programming competition solutions on corner cases.
Always ensure that your recursion does not result in an infinite loop.