applying rule if ad < bc a/b < c/d - c++

im doing a small program , there are 2 arrays , their sizes are the same , lets say its 5 ,
cin >> W;
for (int Q = 0; Q < W; Q++)
cin >> PR[Q] >> CA[Q];
so , my arrays are filled now ,
(numbers are just exampple it doesnot matter i mean their sizes)
1000 300
750 200
950 852
450 250
471 207
now , to understand it better , lets say that on the right side so it means in CA array there are some numbers , which means minutes , literally , and in PR array these numbers are prices , now i need to find the pair which got the smallest price on one minute , normaly i wanted to divide it , but its slow , so i found a rule
if ad < bc then a/b < c/d
but i am not able to use it in the loop everything else is done i mean definitions etc , i just cannot do this "core" how would it look like ?
i also created 2 loops but couldnot implement it correctly
for (int H = 0; H < W; H++) {
for (int B = 0; B < W; B++) {
}
}

You do not need two loops to use the straightforward linear search:
int best = 0;
for (int i = 1 ; i != W ; i++) {
if (pr[i]*ca[best] < pr[best]*ca[i]) {
best = i;
}
}
Note that the loop starts at index 1, not 0, because we do not need to compare the pr[0], ca[0] pair with itself.

Related

Replace duplicate elements in an Array with minimum steps

I should make a program where in a given array of elements I should calculate the minimum amount of elements I should change in order to have no duplicates next to each other.
The windows are in every room and they are all at the same height, so when Mendo walks around the house and looks at them from the outside the windows look like they are stacked in a row. Mendo has three types of colors (white, gray and blue) and wants to color the windows so that there are no two windows that are the same color and are one after the other.
Write a program that will read from the standard input information about the number of windows and the price of coloring each of them with a certain color, and then print the minimum coloring cost of all windows on standard output.
The first line contains an integer N (2 <= N <= 20), which indicates the number of windows. In each of the following N rows are written 3 integers Ai, Bi, Ci (1 <= Ai, Bi, Ci <= 1000), where Ai, Bi, and Ci denote the coloring values of the i window in white , gray and blue, respectively.
Test case:
Input:
3 5 1 5
1 5 5
5 1 1
Output:
3
Also, I should keep in mind that the first element and the last one are considered neighbour-elements.
I started by sorting the array for some reason.
int main()
{
int N;
cin >> N;
int Ai, Bi, Ci;
int A[N * 3];
int A_space = 0;
for (int i = 0; i < N; i++) {
cin >> Ai >> Bi >> Ci;
A[A_space] = Ai;
A[A_space + 1] = Bi;
A[A_space + 2] = Ci;
A_space += 3;
}
for (int i = 0; i < N * 3; i++) {
for (int j = 0; j < N * 3; j++) {
if (A[j] > A[j + 1]) {
swap(A[j], A[j + 1]);
}
}
}
return 0;
}
This problem can be solved by dynamic programming. You will need an N x 3 matrix for this. You will need to calculate the minimum cost of painting the window on each of the 3 colors for each of the N windows. Note that for each color it is enough to take the minimum from the cost of painting N-1 windows on the other two colors because you cannot use the same color 2 times in a row.

Dynamic programming state calculations

Question:
Fox Ciel is writing an AI for the game Starcraft and she needs your help.
In Starcraft, one of the available units is a mutalisk. Mutalisks are very useful for harassing Terran bases. Fox Ciel has one mutalisk. The enemy base contains one or more Space Construction Vehicles (SCVs). Each SCV has some amount of hit points.
When the mutalisk attacks, it can target up to three different SCVs.
The first targeted SCV will lose 9 hit points.
The second targeted SCV (if any) will lose 3 hit points.
The third targeted SCV (if any) will lose 1 hit point.
If the hit points of a SCV drop to 0 or lower, the SCV is destroyed. Note that you may not target the same SCV twice in the same attack.
You are given a int[] HP containing the current hit points of your enemy's SCVs. Return the smallest number of attacks in which you can destroy all these SCVs.
Constraints-
- x will contain between 1 and 3 elements, inclusive.
- Each element in x will be between 1 and 60, inclusive.
And the solution is:
int minimalAttacks(vector<int> x)
{
int dist[61][61][61];
memset(dist, -1, sizeof(dist));
dist[0][0][0] = 0;
for (int total = 1; total <= 180; total++) {
for (int i = 0; i <= 60 && i <= total; i++) {
for (int j = max(0, total - i - 60); j <= 60 && i + j <= total; j++) {
// j >= max(0, total - i - 60) ensures that k <= 60
int k = total - (i + j);
int & res = dist[i][j][k];
res = 1000000;
// one way to avoid doing repetitive work in enumerating
// all options is to use c++'s next_permutation,
// we first createa vector:
vector<int> curr = {i,j,k};
sort(curr.begin(), curr.end()); //needs to be sorted
// which will be permuted
do {
int ni = max(0, curr[0] - 9);
int nj = max(0, curr[1] - 3);
int nk = max(0, curr[2] - 1);
res = std::min(res, 1 + dist[ni][nj][nk] );
} while (next_permutation(curr.begin(), curr.end()) );
}
}
}
// get the case's respective hitpoints:
while (x.size() < 3) {
x.push_back(0); // add zeros for missing SCVs
}
int a = x[0], b = x[1], c = x[2];
return dist[a][b][c];
}
As far as i understand, this solution calculates all possible state's best outcome first then simply match the queried position and displays the result. But I dont understand the way this code is written. I can see that nowhere dist[i][j][k] value is edited. By default its -1. So how come when i query any dist[i][j][k] I get a different value?.
Can someone explain me the code please?
Thank you!

Find a centroid of a dataset

If I have some random data set let's say
X Y
1.2 16
5.7 0.256
128.54 6.879
0 2.87
6.78 0
2.98 3.7
... ...
x' y'
How can I find the centroid coordinates of this data set?
p.s. Here what I tried but got wrong results
float Dim1[K];
float Dim2[K];
float centroidD1[K];
float centroidD2[K];
int K = 4;
int counter[K];
for(int i = 0; i < K ; i++)
{
Dim1[i] = 0;
Dim2[i] = 0;
counter[i] = 0;
for(int j = 0; j < hash["Cluster"].size(); j++)
{
if(hash["Cluster"].value(j) == i+1)
{
Dim1[i] += hash["Dim_1"].value(j);
Dim2[i] += hash["Dim_2"].value(j);
counter[i]++;
}
}
}
for(int l = 0; l < K; l++)
{
centroidD1[l] = Dim1[l] / counter[l];
centroidD2[l] = Dim2[l] / counter[l];
}
I guess I choose wrong algorithm for doing it, as I get wrong results.
Calculating a sum and dividing by N is not a good idea if you have a large data set. As your floating point accumulator grows adding a new point eventually stop working due to the magnitude difference. An incremental formula might work better, see: https://math.stackexchange.com/questions/106700/incremental-averageing
If the issue is too large a data set you can verify the basic functioning of your code by using a smaller data set with a hand verified result. For example, just 1 data point, or 10 data points.

Generating incomplete iterated function systems

I am doing this assignment for fun.
http://groups.csail.mit.edu/graphics/classes/6.837/F04/assignments/assignment0/
There are sample outputs at site if you want to see how it is supposed to look. It involves iterated function systems, whose algorithm according the the assignment is:
for "lots" of random points (x0, y0)
for k=0 to num_iters
pick a random transform fi
(xk+1, yk+1) = fi(xk, yk)
display a dot at (xk, yk)
I am running into trouble with my implementation, which is:
void IFS::render(Image& img, int numPoints, int numIterations){
Vec3f color(0,1,0);
float x,y;
float u,v;
Vec2f myVector;
for(int i = 0; i < numPoints; i++){
x = (float)(rand()%img.Width())/img.Width();
y = (float)(rand()%img.Height())/img.Height();
myVector.Set(x,y);
for(int j = 0; j < numIterations;j++){
float randomPercent = (float)(rand()%100)/100;
for(int k = 0; k < num_transforms; k++){
if(randomPercent < range[k]){
matrices[k].Transform(myVector);
}
}
}
u = myVector.x()*img.Width();
v = myVector.y()*img.Height();
img.SetPixel(u,v,color);
}
}
This is how my pick a random transform from the input matrices:
fscanf(input,"%d",&num_transforms);
matrices = new Matrix[num_transforms];
probablility = new float[num_transforms];
range = new float[num_transforms+1];
for (int i = 0; i < num_transforms; i++) {
fscanf (input,"%f",&probablility[i]);
matrices[i].Read3x3(input);
if(i == 0) range[i] = probablility[i];
else range[i] = probablility[i] + range[i-1];
}
My output shows only the beginnings of a Sierpinski triangle (1000 points, 1000 iterations):
My dragon is better, but still needs some work (1000 points, 1000 iterations):
If you have RAND_MAX=4 and picture width 3, an evenly distributed sequence like [0,1,2,3,4] from rand() will be mapped to [0,1,2,0,1] by your modulo code, i.e. some numbers will occur more often. You need to cut off those numbers that are above the highest multiple of the target range that is below RAND_MAX, i.e. above ((RAND_MAX / 3) * 3). Just check for this limit and call rand() again.
Since you have to fix that error in several places, consider writing a utility function. Then, reduce the scope of your variables. The u,v declaration makes it hard to see that these two are just used in three lines of code. Declare them as "unsigned const u = ..." to make this clear and additionally get the compiler to check that you don't accidentally modify them afterwards.

Find two integers such that their product is close to a given real

I'm looking for an algorithm to find two integer values x,y such that their product is as close as possible to a given double k while their difference is low.
Example: The area of a rectangle is k=21.5 and I want to find the edges length of that rectangle with the constraint that they must be integer, in this case some of the possible solutions are (excluding permutations) (x=4,y=5),(x=3,y=7) and the stupid solution (x=21,y=1)
In fact for the (3,7) couple we have the same difference as for the (21,1) couple
21.5-3*7=0.5 = 21.5-21*1
while for the (4,5) couple
21.5-4*5=1.5
but the couple (4,5) is preferable because their difference is 1, so the rectangle is "more squared".
Is there a method to extract those x,y values for which the difference is minimal and the difference of their product to k is also minimal?
You have to look around square root of the number in question. For 21.5 sqrt(21.5) = 4.6368 and indeed the numbers you found are just around this value.
You want to minimize
the difference of the factors X and Y
the difference of the product X × Y and P.
You have provided an example where these objectives contradict each other. 3 × 7 is closer to 21 than 4 × 5, but the latter factors are more square. Thus, there cannot be any algorithm which minimizes both at the same time.
You can weight the two objectives and transform them into one, and then solve the problem via non-linear integer programming:
min c × |X × Y - P| + d × |X – Y|
subject to X, Y ∈ ℤ
X, Y ≥ 0
where c, d are non-negative numbers that define which objective you value how much.
Take the square root, floor one integer, ceil the other.
#include <iostream>
#include <cmath>
int main(){
double real_value = 21.5;
int sign = real_value > 0 ? 1 : -1;
int x = std::floor(std::sqrt(std::abs(real_value)));
int y = std::ceil(std::sqrt(std::abs(real_value)));
x *= sign;
std::cout << x << "*" << y << "=" << (x*y) << " ~~ " << real_value << "\n";
return 0;
}
Note that this approach only gives you a good distance between x and y, for example if real_value = 10 then x=3 and y=4, but the product is 12. If you want to achieve a better distance between the product and the real value you have to adjust the integers and increase their difference.
double best = DBL_MAX;
int a, b;
for (int i = 1; i <= sqrt(k); i++)
{
int j = round(k/i);
double d = abs(k - i*j);
if (d < best)
{
best = d;
a = i;
b = j;
}
}
Let given double be K.
Take floor of K, let it be F.
Take 2 integer arrays of size F*F. Let they be Ar1, Ar2.
Run loop like this
int z = 0 ;
for ( int i = 1 ; i <= F ; ++i )
{
for ( int j = 1 ; j <= F ; ++j )
{
Ar1[z] = i * j ;
Ar2[z] = i - j ;
++ z ;
}
}
You got the difference/product pairs for all the possible numbers now. Now assign some 'Priority value' for product being close to value K and some other to the smaller difference. Now traverse these arrays from 0 to F*F and find the pair you required by checking your condition.
For eg. Let being closer to K has priority 1 and being smaller in difference has priority .5. Consider another Array Ar3 of size F*F. Then,
for ( int i = 0 ; i <= F*F ; ++i )
{
Ar3[i] = (Ar1[i] - K)* 1 + (Ar2[i] * .5) ;
}
Traverse Ar3 to find the greatest value, that will be the pair you are looking for.