Compiler difference between GCC for c++11 and USACO compiler - c++

For the USACO training gateway exercise humble numbers, I have a solution that works for the first 4 test cases, but then for test case 5 which has been supplied below to circumvent the need for input files, my program gets the correct answer locally when compiled by GCC and on my phone ( not sure what compiler). If I submit the answer to USACO it does not give the correct answer. From what I read that means the program has some undefined behaviour somewhere, but I could not find anything.
#include <fstream>
#include <iostream>
#include <set>
using namespace std;
//ifstream fin("humble.in");
//ofstream fout("humble.out");
set<unsigned long> cont;
int main() {
int K = 6;
int N = 25000;
unsigned long values[]= {2, 3, 5, 7, 11, 13};
cont.insert(1);
unsigned long r = 0;
for (int i = 0; i <= N; i++) {
r = *cont.begin();
for (int j = 0; j < K; j++)
cont.insert(r*values[j]);
cont.erase(r);
}
cout << r << endl;
return 0;
}
The answer I get locally (and the correct answer) is 682628310.
The answer I get on USACO is 67108864.

Related

Do not know how to implement a thing in a homework task

Now, the question is :
Assemble a program that will simulate the work of automatic telephone exchanges. For example, there are 10 subscribers, anyone can call anyone, Each has several conditions:
waiting for an answer, calls, says, free. They randomly call each other, the program should show the operation of this system.
And, I figured out how to do some of it, but, don't know how to exactly implement it.
#include <cstdlib>
#include <chrono>
#include <random>
#include <string>
using namespace std;
int i, a;
string state[4]{ "free", "waiting", "calling", "talking" };
int states[4]{ 1,2,3,4 };
int subs[10]{ 1,2,3,4,5,6,7,8,9,10 };
int main(int subs[10], int states[4], string state[4])
{
srand(time(nullptr));
for (int x = 0; x < subs[10]; x++)
{
states[i] = rand() % 4;
states[i] = a;
cout << "Subscriber" << subs[x] << "is" << state[a] << endl << endl;
}
}
Right here, I also have an error in line states[i] = a
Now, what I tried to do there was to randomize a number, and then let it get assigned to any subscriber, and then showed to the person who runs the program. But, well... This is not exactly what the question told me to do. And, I am not sure what I can do, here. I also have limited time for this, with only 12 hours left to do this, because I am a lazy bum. Help please?
Clear version of your code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(void) {
int subs[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
size_t len = sizeof(subs) / sizeof(subs[0]);
string subsStatus[10];
string state[] = {"CALLING", "WAITING", "FREE", "TALKING"};
srand(time(NULL));
for (int i = 0; i < len; i++) {
subsStatus[i] = state[rand() % 4]; // example: Subscriber4 = "TALKING"[3]
cout << "Subscriber" << subs[i] << " is " << subsStatus[i] << endl;
}
return 0;
}
There are some guidelines as side tip:
You don't need to use nullptr in srand(time())
If I'm right, then the function main() is only supposed to accept int argc, char *argv[] and few more arguments, don't define your owns since you're not asking before launch of program from terminal.
states[i] = a defines states[i] to a not vice versa.
You don't need to define array length in case you're defining via coding, i.e. int arr[] = {...}, it'll be expanded automatically, you must use c++11 and above for this feature.

How to find the minimun of an array?

I was trying to solve this question
but codechef.com says the answer is wrong.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t, n, diff, mindiff;
cin >> t;
cin >> n;
int val[n];
while(t--)
{
mindiff = 1000000000;
for(int i = 0; i<n; i++)
{
cin >> val[i];
}
int a = 0;
for(a = 0; a<n ; a++)
{
for(int b=a+1; b<n ; b++)
{
diff = abs(val[a] - val[b]);
if(diff <= mindiff)
{
mindiff = diff;
}
}
}
cout << mindiff << endl;
}
return 0;
}
The results are as expected (for at least the tests I did) buts the website says its wrong.
There are a few things in your code that you should change:
Use std::vector<int> and not variable-length arrays (VLA's):
Reasons:
Variable length arrays are not standard C++. A std::vector is standard C++.
Variable length arrays may exhaust stack memory if the number of entries is large. A std::vector gets its memory from the heap, not the stack.
Variable length arrays suffer from the same problem as regular arrays -- going beyond the bounds of the array leads to undefined
behavior. A std::array has an at() function that can check boundary access when desired.
Use the maximum int to get the maximum integer value.
Instead of
mindif = 1000000000;
it should be:
#include <climits>
//...
int mindiff = std::numeric_limits<int>::max();
As to the solution you chose, the comments in the main section about the nested loop should be addressed.
Instead of a nested for loop, you should sort the data first. Thus finding the minimum value between two values is much easier and with less time complexity.
The program can look something like this (using the data provided at the link):
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
int main()
{
int n = 5;
std::vector<int> val = {4, 9, 1, 32, 13};
int mindiff = std::numeric_limits<int>::max();
std::sort(val.begin(), val.end());
for(int a = 0; a < n-1 ; a++)
mindiff = std::min(val[a+1] - val[a], mindiff);
std::cout << mindiff;
}
Output:
3
To do this you can use a simple for():
// you already have an array called "arr" which contains some numbers.
int biggestNumber = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr[i] > biggestNumber) {
biggestNumber = arr[i];
}
}
arr.size will get the array's length so that you can check every value from the position 0 to the last one which is arr.size() - 1 (because arrays are 0 based in c++).
Hope this helps.

USACO grader giving different response than my machine

I am working on a USACO task and the grader outputs 4, while my machine gives 3, the correct answer.
The input is:
4
7 Mildred +3
4 Elsie -1
9 Mildred -1
1 Bessie +2
I have run this through a debugger and no issues were found.
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <fstream>
using namespace std;
int N, bmilk=7, emilk=7, mmilk=7;
int bboard=0, eboard=0, mboard=0;
int ans=0;
vector<pair<int,pair<string,int>>> a;
int main()
{
ofstream fout("measurement.out");
ifstream fin("measurement.in");
fin >> N;
for (int i = 0; i < N; i++)
{
int d, chg;
string c;
fin >> d >> c >> chg;
a.push_back(make_pair(d,make_pair(c,chg)));
}
sort(a.begin(), a.end());
for (int i = 0; i < N; i++)
{
if (a[i].second.first=="Bessie") bmilk+=a[i].second.second;
else if (a[i].second.first=="Elsie") emilk+=a[i].second.second;
else mmilk+=a[i].second.second;
int best_milk = max(bmilk,max(emilk,mmilk));
int curr_board[4];
for (int j = 0; j < 3; j++) curr_board[i]=0;
if (bmilk==best_milk) curr_board[0]=1;
if (emilk==best_milk) curr_board[1]=1;
if (mmilk==best_milk) curr_board[2]=1;
if (curr_board[0]!=bboard||curr_board[1]!=eboard||curr_board[2]!=mboard)
{
ans++;
bboard=curr_board[0];
eboard=curr_board[1];
mboard=curr_board[2];
}
}
fout << ans << "\n";
return 0;
}
Can anybody please help me find what is causing this error?
You read uninitialized elements of curr_board, and you potentially overrun it as well.
The problem is that the line intended to initialize multiple elements, instead assigns the same element over and over:
for (int j = 0; j < 3; j++) curr_board[i]=0;
Reading uninitialized values is undefined behavior and could easily cause different outcomes on different machines. Ditto for out-of-bounds access.
Why does curr_board have size 4 anyway?

Segment Fault due to scope of variable

I am a beginner to C++.
I am trying to read in input from the console, so I have the code below:
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
#define maxn 2006
int A[maxn][maxn];
int main() {
memset(A,0,sizeof(A));
int n = 0,m = 0;
cin >> n >> m;
for(int i = 0; i < n; ++i){
string str; cin >> str;
for(int j =0; j < m; ++j)
A[i][j] = str[j]-'0';
}
return 0;
}
A sample input looks like this
5 7
0101010
1000101
0101010
1010101
0101010
My program above works perfectly.
However, for learning purpose, I did nothing but move the declaration of 2D int array A into the main function, which looks like this:
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
#define maxn 2006
int main() {
int A[maxn][maxn];
memset(A,0,sizeof(A));
int n = 0,m = 0;
cin >> n >> m;
for(int i = 0; i < n; ++i){
string str; cin >> str;
for(int j =0; j < m; ++j)
A[i][j] = str[j]-'0';
}
return 0;
}
I rebuild it and run, I get segmentation fault 11.
Anyone know what's going on here? Why does the code break down after the subtle change?
Thanks!
Anyone know what's going on here?
Yes: stack overflow.
By moving the variable you made it a local (stack allocated) instead of global (allocated at startup in the BSS section of the binary).
The size of your variable is 16,096,144 bytes (2006 * 2006 * 4). And stack is usually limited, often to 8MB. On a UNIX system, after ulimit -s unlimited, your modified program may start working again.

how to generate evenly distributed n-permutation from range 0 to m (m<n)

repeating of a number is allowed but the probability is limited
for example:
giving a number sequence 0-8,i want to generate a 25 number random sequence,the max repeate time of a digit is 3.
One relatively foolproof method is rejection sampling. Generate 25 numbers independently. If any number appears more than 3 times, throw them all away and try again. This method has poor worst-case performance, but it's so simple that you won't have to worry that you've accidentally introduced unwanted correlations.
As far as I understand you need something like this (Reworked according to comment below):
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <iostream>
using std::vector;
using std::cout;
vector<int> Generate(const vector<int> & numbers, int generateN, int maxRepeatN)
{
vector<int> longList(numbers.size() * maxRepeatN);
for(int i = 0; i < numbers.size(); i++)
for(int j = 0; j < maxRepeatN; j++)
longList[i * maxRepeatN + j] = numbers[i];
vector<int> result(generateN);
for(int i = 0; i < generateN; i++)
{
int id = rand() % longList.size();
result[i] = longList[id];
longList.erase(longList.begin() + id);
}
return result;
}
int main()
{
srand((unsigned)time(0));
vector<int> numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8}
vector<int> result = Generate(numbers, 25, 3);
for(int i = 0; i < result.size(); i++)
cout << result[i] << " ";
return 0;
}
Idea of algorithm is that you create long list of all possible digits to get (it guarantees that you won't get more than a max digits of one type). Then you get digits one by one from it (removing digits after getting from long list guarantees distribution).
*This code is for example only and such use of std::vector is not optimal at all.