there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}
I'm reviewing some numerical methods for integration. I came across Rectangular integration method (i.e. Euler's method). According to the book I'm reading, the actual algorithm is
The code is self-explanatory. The author provides this example dxdt=cos(t) with an initial value x(0)=0. The analytical solution is x=sin(t). We can compute the error at t=1 and indeed the author provides it in the following table:
The problem is that in my following code, the error is 9.1% but in the preceding table, the error actually is 2.6. Did I make a mistake?
#include <iostream>
#include <cmath>
int main()
{
double x(0.0), dxdt, t(0.0), T(0.1), stopTime(1.0);
for ( ; t <= stopTime; t += T ){
dxdt = cos(t);
x += dxdt*T;
if ( t > 0.9 )
std::cout << "Time: " << t << " Error: " << fabs( (x - sin(t)) /sin(t) )*100.0 << std::endl;
}
return 0;
}
You need to take into account that while x is updated to an approximation of x(t+T), the loop variable t will only be incremented at the very end of the loop, so retains it value t during the output. This time mismatch introduces an additional relative error of abs(sin(t+T)/sin(t)-1) which for t=1, T=0.1 is about 5.91 %.
You should also make the loop stable under rounding errors in the t incrementation, either by computing the exact number of loops or by choosing bounds in the inequality that are in-between the steps as in
while ( t < stopTime-0.5*T ){
dxdt = cos(t);
x += dxdt*T;
t += T;
if ( t > stopTime -2.5*T )
std::cout << "Time: " << t << " Error: " << fabs( (x - sin(t)) /sin(t) )*100.0 << std::endl;
}
Could you like to tell how to split clauses of unsat cores?
And here is question 2 regarding after found out unsat cores, I will try to seek again.
Would you like to tell how to do this?
Thank you very much.
How to split the clauses as below
`and` (`or` (`<=_int` 1002 x1) (`<=_int` 1000 x1)) (`and` (`or` (`<=_int` 0 (`+_int` x2 (`*_int` -1003 x1))) (`<=_int` 0 (`+_int` x2 (`*_int` -1230 x1)))) (`and` (`or` (`<=_int` 0 (`+_int` x3 (`*_int` -1999 x2)))
Regarding to the question 2,
cout<<s.check(3,assumptions)<<endl;
expr_vector core = s.unsat_core();
................
expr assumptions2[2] = {p1,p3};
cout<<"check next"<<s.check(2,assumptions2)<<endl;
expr_vector core1 = s.unsat_core();
for(unsigned int k=0;k<core1.size();++k){
cout<<"New core size "<<k<<endl;
cout<<"New unsat core "<<core1[k]<<endl;
}
calling the unsat core function again, it cannot give the unsat cores again.
Thank you very much.
I'm not sure if I understood your question. It seems you have an assertion of the form (and c1 (and c2 c3)), and you want to track c1, c2 and c3 individually.
In Z3, we use answer literals to track assertions. An answer literal is essentially a fresh Boolean that is used to track an assertion. That is, whether the assertion was used (by Z3) to show unsatisfiability of the whole set of assertions or not. For example, if we want to track assertion F, we create a fresh Boolean variable p and assert p implies F. Then, we provide p as an argument for the check method.
If F is a big conjunction and we want to track its elements individually, we should extract its elements and create an answer literal for each one of them. Here is the complete example that does the trick. You can test it by including it in the example.cpp file that is included in the Z3 distribution. Note that you have to include #include<vector>.
/**
\brief Unsat core example 2
*/
void unsat_core_example2() {
std::cout << "unsat core example 2\n";
context c;
// The answer literal mechanism, described in the previous example,
// tracks assertions. An assertion can be a complicated
// formula containing containing the conjunction of many subformulas.
expr p1 = c.bool_const("p1");
expr x = c.int_const("x");
expr y = c.int_const("y");
solver s(c);
expr F = x > 10 && y > x && y < 5 && y > 0;
s.add(implies(p1, F));
expr assumptions[1] = { p1 };
std::cout << s.check(1, assumptions) << "\n";
expr_vector core = s.unsat_core();
std::cout << core << "\n";
std::cout << "size: " << core.size() << "\n";
for (unsigned i = 0; i < core.size(); i++) {
std::cout << core[i] << "\n";
}
// The core is not very informative, since p1 is tracking the formula F
// that is a conjunction of subformulas.
// Now, we use the following piece of code to break this conjunction
// into individual subformulas. First, we flat the conjunctions by
// using the method simplify.
std::vector<expr> qs; // auxiliary vector used to store new answer literals.
assert(F.is_app()); // I'm assuming F is an application.
if (F.decl().decl_kind() == Z3_OP_AND) {
// F is a conjunction
std::cout << "F num. args (before simplify): " << F.num_args() << "\n";
F = F.simplify();
std::cout << "F num. args (after simplify): " << F.num_args() << "\n";
for (unsigned i = 0; i < F.num_args(); i++) {
std::cout << "Creating answer literal q" << i << " for " << F.arg(i) << "\n";
std::stringstream qname; qname << "q" << i;
expr qi = c.bool_const(qname.str().c_str()); // create a new answer literal
s.add(implies(qi, F.arg(i)));
qs.push_back(qi);
}
}
// The solver s already contains p1 => F
// To disable F, we add (not p1) as an additional assumption
qs.push_back(!p1);
std::cout << s.check(qs.size(), &qs[0]) << "\n";
expr_vector core2 = s.unsat_core();
std::cout << core2 << "\n";
std::cout << "size: " << core2.size() << "\n";
for (unsigned i = 0; i < core2.size(); i++) {
std::cout << core2[i] << "\n";
}
}
I want to increment a double value from the smallest possible (negative) value it can take to the largest possible value it can take.
I've started off with this:
int main()
{
double min(numeric_limits<double>::min());
double i(min);
while(i < 0);
{
cout << i << endl;
i += min ;
}
}
Unfortunately, this doesn't produce the desired result - the while loop is skipped after one iteration.
Is there a better way to accomplish my goal?
I'm guessing at what you want from your code: You want to start with largest possible negative value and increment it toward positive infinity in the smallest possible steps until the value is no longer negative.
I think the function you want is nextafter().
int main() {
double value(-std::numeric_limits<double>::max());
while(value < 0) {
std::cout << value << '\n';
value = std::nextafter(value,std::numeric_limits<double>::infinity());
}
}
Firstly,
while(i < 0); // <--- remove this semicolon
{
cout << i << endl;
i += min ;
}
Then, std::numeric_limits<double>::min() is a positive value, so i < 0 will never be true. If you need the most negative value, you'll need
double min = -std::numeric_limits<double>::max();
but I don't know what your i += min line is supposed to do. Adding two most negative number will just yield −∞, and the loop will never finish. If you want to add a number, you'll need another variable, like
double most_negative = -std::numeric_limits<double>::max();
double most_positive = std::numeric_limits<double>::max();
double i = most_negative;
while (i < 0)
{
std::cout << i << std::endl;
i += most_positive;
}
Of course this will just print the most negative number (-1.8e+308), and then i becomes 0 and the loop will exit.
The following runs through all float-values 'in order'. The steps between successive values become smaller as u.mind increases.
No guarantee this is correct and it will take a long time to complete and this isn't portable and it will take even longer for doubles and... etc. etc.
#include <cassert>
#include <iostream>
#include <limits>
union umin {
float mind;
int mini;
} u;
int main()
{
u.mind = std::numeric_limits<float>::max();
std::cout << -u.mind << " " << u.mini << std::endl;
while ( u.mind > 0 ) {
float previous = u.mind;
u.mini -= 1;
std::cout << -u.mind << " " << u.mini << " " << previous - u.mind << std::endl;
assert( previous > u.mind );
}
}
What I mean is the following:
double d1 =555;
double d2=55.343
I want to be able to tell that d1 is an integer while d2 is not. Is there an easy way to do it in c/c++?
Use std::modf:
double intpart;
modf(value, &intpart) == 0.0
Don't convert to int! The number 1.0e+300 is an integer too you know.
Edit: As Pete Kirkham points out, passing 0 as the second argument is not guaranteed by the standard to work, requiring the use of a dummy variable and, unfortunately, making the code a lot less elegant.
Assuming a c99 and IEEE-754 compliant environment,
(trunc(x) == x)
is another solution, and will (on most platforms) have slightly better performance than modf because it needs only to produce the integer part. Both are completely acceptable.
Note that trunc produces a double-precision result, so you don't need to worry about out of range type conversions as you would with (int)x.
Edit: as #pavon points out in a comment, you may need to add another check, depending on whether or not you care about infinity, and what result you want to get if x is infinite.
Assuming you have the cmath <math.h> library, you can check the number against it's floor. If the number might be negative, make sure you get the absolute first.
bool double_is_int(double trouble) {
double absolute = abs( trouble );
return absolute == floor(absolute);
}
avakar was almost right - use modf, but the detail was off.
modf returns the fractional part, so the test should be that the result of modf is 0.0.
modf takes two arguments, the second of which should be a pointer of the same type as the first argument. Passing NULL or 0 causes a segmentation fault in the g++ runtime. The standard does not specify that passing 0 is safe; it might be that it happens to work on avakar's machine but don't do it.
You could also use fmod(a,b) which calculates the a modulo b passing 1.0. This also should give the fractional part.
#include<cmath>
#include<iostream>
int main ()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;
cout.flush();
modf ( d1, 0 ); // segfault
}
int iHaveNoFraction(double d){
return d == trunc(d);
}
Now, it wouldn't be C if it didn't have about 40 years of language revisions...
In C, == returns int but in C++ it returns bool. At least on my Linux distro (Ubuntu) you need to either declare double trunc(double); or you could compile with -std=c99, or declare the level macro, all in order to get <math.h> to declare it.
How about
if (abs(d1 - (round(d1))) < 0.000000001) {
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Fixed up to work using rounding to reflect bug Anna found
Alternate solutions:
if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
/* Better store floor value in a temp variable to speed up */
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Theres also another one with taking floor, subtracting 0.5 and taking abs() of that and comparing to 0.499999999 but I figure it won't be a major performance improvement.
Just compare ceil and floor value of d
return floor(d)==ceil(d);
So, for d1=555, the above statement will return 555==555, i.e, true, so it's an integer.
And for d2=555.6, the above statement will return 555==556, i.e, false, so it's a double.
How about this?
if ((d1 - (int)d1) == 0)
// integer
#define _EPSILON_ 0.000001
bool close_to_int(double &d)
{
double integer,
fraction = modf(d, &integer);
if(fraction < _EPSILON_)
{
d = integer;
return true;
}
if((1.0 - fraction) < _EPSILON_)
{
d = integer + 1;
return true;
}
return false;
}
This looks at both side of the integer value and sets the value of d if it is within the limits of an integer value.
try:
bool isInteger(double d, double delta)
{
double absd = abs(d);
if( absd - floor(absd) > 0.5 )
return (ceil(absd) - absd) < delta;
return (d - floor(absd)) < delta;
}
#include <math.h>
#include <limits>
int main()
{
double x, y, n;
x = SOME_VAL;
y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
if ( abs(y) < std::numeric_limits<double>::epsilon() )
{
// no floating part
}
}
In many calculations you know that your floating point results will have a small numerical error that can result from a number of multiplications.
So what you may really want to find is the question is this number within say 1e-5 of an integer value. In that case I think this works better:
bool isInteger( double value )
{
double flr = floor( value + 1e-5 );
double diff = value - flr;
return diff < 1e-5;
}
I faced a similar questions.
As I needed to round the double anyway, that's what I find working:
double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
modf uses std::nearbyint(num) that why you should use nearbyint which return a double without decimal and may be faster.
#include <iostream>
#include <cmath>
int main() {
double number = 55.12;
if (!(number - std::nearbyint(number))) {
std::cout << "Is integer!";
} else {
std::cout << "Has decimal!";
}
return 0;
}
A sample code snipped that does it:
if ( ABS( ((int) d1) - (d1)) )< 0.000000001)
cout <<"Integer" << endl;
else
cout <<"Flaot" << endl;
EDIT: Changed it to reflect correct code.
Below you have the code for testing d1 and d2 keeping it very simple. The only thing you have to test is whether the variable value is equal to the same value converted to an int type. If this is not the case then it is not an integer.
#include<iostream>
using namespace std;
int main()
{
void checkType(double x);
double d1 = 555;
double d2 = 55.343;
checkType(d1);
checkType(d2);
system("Pause");
return 0;
}
void checkType(double x)
{
if(x != (int)x)
{
cout<< x << " is not an integer "<< endl;
}
else
{
cout << x << " is an integer " << endl;
}
};