I'm using a sequence of x numbers and search the lower and higher number of it and calculate the diff, but when I use a variable to save the highest number it don't save, I don't have that problem with the lower variable.
for(int i=0;i<mesos;i++){
cin >>m;
if(m<e) a = m;
else if(m<e) e = m;
all is declared
Just for elegance as this is a C++ question.
uint64_t min, max;
for(decltype(mesos) i = 0; i < mesos; ++i) {
std::cin >> m;
min = std::min(min, m);
max = std::max(max, m);
}
To save the highest number you have to test if the number is greater than another number. In your case you're calculating against the same value, the same thing. I didn't test my resolution but it would be something like what I wrote bellow. I used an if in the first time the loop runs so the highest and the lowest value are equal your input.
But test also gonewiththewhind answer, and see which is best for you.
Tip: use good variable names
int lower,higher;
for(int i=0;i<mesos;i++){
cin >> m;
if(i==0){
lower = m;
higher = m;
}
if(m>higher) higher = m;
else if(m<lower) lower = m;
}
my program seems correct but I don't know why it has a logic problem
int main()
{
int r,s=0;
for(int i=10000;i<=998001;i++)
{
while (i>0)
{
r=i%10;
s=s*10+r;
i=i/10;
}
cout<<s<<endl;
}
Your question and code don't seem to match Ali. You have told that you need the largest possible palindrome, but you are printing each and every reversed number. And your code has glitches too. I will list the mistakes and corresponding changes to be made:
using i as both the for loop counter variable and as well as the number you're reversing. This causes i to become 0 after every reversal and hence the for loop never ends. The fix for this... use another variable, say num, and equate it to i at the start of the loop. This ensures that i remains unchanged and for goes unfazed.
use long int instead of int. This avoids any anomalies and chances of junk numbers.
s(the sum variable) is initialized only at the start. Hence every time you calculate a new reversed number, it is adding s to its previous value. The fix: Initialize s to 0 at the start of for loop so that you get a fresh reversed for every i value.
You are not checking for any palindrome condition. You are just printing the reversed number. The fix: Hence check if the the number is a palindrome, i.e, if the number ,i.e., i is equal to the reversed number, i.e., s
I have attached the code below. I am currently printing the greatest palindrome in the range in which you were checking. In case you need all the palindromes, just uncomment the commented cout line.
CODE:
#include <iostream>
using namespace std;
int main()
{
int r, s = 0;
long int num, max = 0;
for(long int i = 10000; i <= 998001; i++)
{
s = 0;
num = i;
while (num > 0)
{
r = num % 10;
s = s * 10 + r;
num = num / 10;
}
if(s == i) {
//cout<<s<<endl; //uncomment this line if you intend to display all palindromes
if(i > max)
max = i;
}
}
cout<<max<<endl;
}
I am a beginner in c++ and I am having problems with making this code work the way I want it to. The task is to write a program that multiplies all the natural numbers up to the loaded number n.
To make it print the correct result, I divided x by n (see code below). How can I make it print x and not have to divide it by n to get the correct answer?
#include<iostream>
using namespace std;
int main(){
int n,x=1;
int i=0;
cout<<"Enter a number bigger than 0:"<<endl;
cin>>n;
while(i<n){
i++;
x=i*x;
};
cout<<"The result is: "<<x/n<<endl;
return 0;
}
At very first a principle you best get used to as quickly as possible: Always check user input for correctness!
cin >> n;
if(cin && n > 0)
{
// valid
}
else
{
// appropriate error handling
}
Not sure, why do you need a while loop? A for loop sure is nicer in this case:
int x = 1;
for(int i = 2; i < n; ++i)
x *= i;
If you still want the while loop: Start with i == 2 (1 is neutral anyway) and increment afterwards:
i = 2;
while(i < n)
{
x *= i;
++i;
}
In case of n == 1, the loop (either variant) simply won't be entered and you are fine...
You already have two very good options, but here is an other one you might want to take a look at when you are at ease enough in programming :
unsigned factorial(unsigned value)
{
if (value <= 1)
{
return 1;
}
else
{
return value * factorial(value - 1);
}
}
It's a recursive function, which is kind of neat when used in proper moments (which could not be the case here unfortunately because the execution stack might get so big you fill your memory before you're done. But you can check it out to learn more about recursive functions)
When your memory is full, you then crash your app with what is called actually a stack overflow.
How can I make it so that in the last cout I can only put x and not have to divide x by n to get the correct answer?
It will be better to use a for loop.
// This stops when i reaches n.
// That means, n is not multiplied to the result when the loop breaks.
for (int i = 1; i < n; ++i )
{
x *= i;
}
cout << "The result is: " << x <<endl;
I solved this problem but I got TLE Time Limit Exceed on online judge
the output of program is right but i think the way can be improved to be more efficient!
the problem :
Given n integer numbers, count the number of ways in which we can choose two elements such
that their absolute difference is less than 32.
In a more formal way, count the number of pairs (i, j) (1 ≤ i < j ≤ n) such that
|V[i] - V[j]| < 32. |X|
is the absolute value of X.
Input
The first line of input contains one integer T, the number of test cases (1 ≤ T ≤ 128).
Each test case begins with an integer n (1 ≤ n ≤ 10,000).
The next line contains n integers (1 ≤ V[i] ≤ 10,000).
Output
For each test case, print the number of pairs on a single line.
my code in c++ :
int main() {
int T,n,i,j,k,count;
int a[10000];
cin>>T;
for(k=0;k<T;k++)
{ count=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(i!=j)
{
if(abs(a[i]-a[j])<32)
count++;
}
}
}
cout<<count<<endl;
}
return 0;
}
I need help how can I solve it in more efficient algorithm ?
Despite my previous (silly) answer, there is no need to sort the data at all. Instead you should count the frequencies of the numbers.
Then all you need to do is keep track of the number of viable numbers to pair with, while iterating over the possible values. Sorry no c++ but java should be readable as well:
int solve (int[] numbers) {
int[] frequencies = new int[10001];
for (int i : numbers) frequencies[i]++;
int solution = 0;
int inRange = 0;
for (int i = 0; i < frequencies.length; i++) {
if (i > 32) inRange -= frequencies[i - 32];
solution += frequencies[i] * inRange;
solution += frequencies[i] * (frequencies[i] - 1) / 2;
inRange += frequencies[i];
}
return solution;
}
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int N;
int search (int x){
int low = 0;
int high = N;
while (low < high)
{
int mid = (low+high)/2;
if (a[mid] >= x) high = mid;
else low = mid+1;
}
return low;
}
int main() {
cin >> N;
for (int i=0 ; i<N ; i++) cin >> a[i];
sort(a,a+N);
long long ans = 0;
for (int i=0 ; i<N ; i++)
{
int t = search(a[i]+32);
ans += (t -i - 1);
}
cout << ans << endl;
return 0;
}
You can sort the numbers, and then use a sliding window. Starting with the smallest number, populate a std::deque with the numbers so long as they are no larger than the smallest number + 31. Then in an outer loop for each number, update the sliding window and add the new size of the sliding window to the counter. Update of the sliding window can be performed in an inner loop, by first pop_front every number that is smaller than the current number of the outer loop, then push_back every number that is not larger than the current number of the outer loop + 31.
One faster solution would be to first sort the array, then iterate through the sorted array and for each element only visit the elements to the right of it until the difference exceeds 31.
Sorting can probably be done via count sort (since you have 1 ≤ V[i] ≤ 10,000). So you get linear time for the sorting part. It might not be necessary though (maybe quicksort suffices in order to get all the points).
Also, you can do a trick for the inner loop (the "going to the right of the current element" part). Keep in mind that if S[i+k]-S[i]<32, then S[i+k]-S[i+1]<32, where S is the sorted version of V. With this trick the whole algorithm turns linear.
This can be done constant number of passes over the data, and actually can be done without being affected by the value of the "interval" (in your case, 32).
This is done by populating an array where a[i] = a[i-1] + number_of_times_i_appears_in_the_data - informally, a[i] holds the total number of elements that are smaller/equals to i.
Code (for a single test case):
static int UPPER_LIMIT = 10001;
static int K = 32;
int frequencies[UPPER_LIMIT] = {0}; // O(U)
int n;
std::cin >> n;
for (int i = 0; i < n; i++) { // O(n)
int x;
std::cin >> x;
frequencies[x] += 1;
}
for (int i = 1; i < UPPER_LIMIT; i++) { // O(U)
frequencies[i] += frequencies[i-1];
}
int count = 0;
for (int i = 1; i < UPPER_LIMIT; i++) { // O(U)
int low_idx = std::max(i-32, 0);
int number_of_elements_with_value_i = frequencies[i] - frequencies[i-1];
if (number_of_elements_with_value_i == 0) continue;
int number_of_elements_with_value_K_close_to_i =
(frequencies[i-1] - frequencies[low_idx]);
std::cout << "i: " << i << " number_of_elements_with_value_i: " << number_of_elements_with_value_i << " number_of_elements_with_value_K_close_to_i: " << number_of_elements_with_value_K_close_to_i << std::endl;
count += number_of_elements_with_value_i * number_of_elements_with_value_K_close_to_i;
// Finally, add "duplicates" of i, this is basically sum of arithmetic
// progression with d=1, a0=0, n=number_of_elements_with_value_i
count += number_of_elements_with_value_i * (number_of_elements_with_value_i-1) /2;
}
std::cout << count;
Working full example on IDEone.
You can sort and then use break to end loop when ever the range goes out.
int main()
{
int t;
cin>>t;
while(t--){
int n,c=0;
cin>>n;
int ar[n];
for(int i=0;i<n;i++)
cin>>ar[i];
sort(ar,ar+n);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(ar[j]-ar[i] < 32)
c++;
else
break;
}
}
cout<<c<<endl;
}
}
Or, you can use a hash array for the range and mark occurrence of each element and then loop around and check for each element i.e. if x = 32 - y is present or not.
A good approach here is to split the numbers into separate buckets:
constexpr int limit = 10000;
constexpr int diff = 32;
constexpr int bucket_num = (limit/diff)+1;
std::array<std::vector<int>,bucket_num> buckets;
cin>>n;
int number;
for(i=0;i<n;i++)
{
cin >> number;
buckets[number/diff].push_back(number%diff);
}
Obviously the numbers that are in the same bucket are close enough to each other to fit the requirement, so we can just count all the pairs:
int result = std::accumulate(buckets.begin(), buckets.end(), 0,
[](int s, vector<int>& v){ return s + (v.size()*(v.size()-1))/2; });
The numbers that are in non-adjacent buckets cannot form any acceptable pairs, so we can just ignore them.
This leaves the last corner case - adjacent buckets - which can be solved in many ways:
for(int i=0;i<bucket_num-1;i++)
if(buckets[i].size() && buckets[i+1].size())
result += adjacent_buckets(buckets[i], buckets[i+1]);
Personally I like the "occurrence frequency" approach on the one bucket scale, but there may be better options:
int adjacent_buckets(const vector<int>& bucket1, const vector<int>& bucket2)
{
std::array<int,diff> pairs{};
for(int number : bucket1)
{
for(int i=0;i<number;i++)
pairs[i]++;
}
return std::accumulate(bucket2.begin(), bucket2.end(), 0,
[&pairs](int s, int n){ return s + pairs[n]; });
}
This function first builds an array of "numbers from lower bucket that are close enough to i", and then sums the values from that array corresponding to the upper bucket numbers.
In general this approach has O(N) complexity, in the best case it will require pretty much only one pass, and overall should be fast enough.
Working Ideone example
This solution can be considered O(N) to process N input numbers and constant in time to process the input:
#include <iostream>
using namespace std;
void solve()
{
int a[10001] = {0}, N, n, X32 = 0, ret = 0;
cin >> N;
for (int i=0; i<N; ++i)
{
cin >> n;
a[n]++;
}
for (int i=0; i<10001; ++i)
{
if (i >= 32)
X32 -= a[i-32];
if (a[i])
{
ret += a[i] * X32;
ret += a[i] * (a[i]-1)/2;
X32 += a[i];
}
}
cout << ret << endl;
}
int main()
{
int T;
cin >> T;
for (int i=0 ; i<T ; i++)
solve();
}
run this code on ideone
Solution explanation: a[i] represents how many times i was in the input series.
Then you go over entire array and X32 keeps track of number of elements that's withing range from i. The only tricky part really is to calculate properly when some i is repeated multiple times: a[i] * (a[i]-1)/2. That's it.
You should start by sorting the input.
Then if your inner loop detects the distance grows above 32, you can break from it.
Thanks for everyone efforts and time to solve this problem.
I appreciated all Attempts to solve it.
After testing the answers on online judge I found the right and most efficient solution algorithm is Stef's Answer and AbdullahAhmedAbdelmonem's answer also pavel solution is right but it's exactly same as Stef solution in different language C++.
Stef's code got time execution 358 ms in codeforces online judge and accepted.
also AbdullahAhmedAbdelmonem's code got time execution 421 ms in codeforces online judge and accepted.
if they put detailed explanation to there algorithm the bounty will be to one of them.
you can try your solution and submit it to codeforces online judge at this link after choosing problem E. Time Limit Exceeded?
also I found a great algorithm solution and more understandable using frequency array and it's complexity O(n).
in this algorithm you only need to take specific range for each inserted element to the array which is:
begin = element - 32
end = element + 32
and then count number of pair in this range for each inserted element in the frequency array :
int main() {
int T,n,i,j,k,b,e,count;
int v[10000];
int freq[10001];
cin>>T;
for(k=0;k<T;k++)
{
count=0;
cin>>n;
for(i=1;i<=10000;i++)
{
freq[i]=0;
}
for(i=0;i<n;i++)
{
cin>>v[i];
}
for(i=0;i<n;i++)
{
count=count+freq[v[i]];
b=v[i]-31;
e=v[i]+31;
if(b<=0)
b=1;
if(e>10000)
e=10000;
for(j=b;j<=e;j++)
{
freq[j]++;
}
}
cout<<count<<endl;
}
return 0;
}
finally i think the best approach to solve this kind of problems to use frequency array and count number of pairs in specific range because it's time complexity is O(n).
Find Maximum sum in an array such that no 2 elements are adjacent. In this, 1 more condition was also there that first and last elements should also not be taken together.
If it would have been without the last condition, that is, then I developed the following code wherein I take two variables, incl and excl and find out the values. It is as follows:
#include <iostream>
using namespace std;
int main (void)
{
int i,n;
cin>>n;
int arr[100];
for ( i = 0; i < n; i++ )
cin>>arr[i];
int incl,excl,excls;
incl = arr[0];
for ( i = 1; i < n; i++ )
{
if (incl > excl)
excls = incl;
else
excls = excl;
incl = excl + arr[i];
excl = excls;
}
if (incl > excl)
cout<<incl;
else
cout<<excl;
cout<<"\n";
return 0;
}
How can I modify this for that special case? Thanks!
To account for the special case, you could run your existing algorithm twice.
The first time you compute the best sum over the first n-1 elements in the array. This will calculate the best sum that definitely does not include the last element.
The second time you compute the best sum over the last n-1 elements in the array. This will calculate the best sum that definitely does not include the first element.
The best answer will be the best of these two results.
(by the way, you are not initializing the variable excl so you may get incorrect results sometimes)