C++ Matrix combinations - c++

Firstly thanks for reading.I'm trying to make a "noob" program and i wanted to use a registration code.
For completing my encryption algorythm i need to generate all 4x4 matrices containing only numbers from 0 to 9 like in the following example:
4 4 6 8
5 2 4 3
8 5 2 9
2 7 2 6
I know there is a huge number of these combinations but it wont stop me.I tried myself to do it using "for" but i can't figure it out.

I would store the 4x4 digit matrix as char[16], interpreting the first four chars as the first row, the next four chars as the second row, etc. You can easily generate all possible values by recursion, with a for loop on each level.
void print_all_possible_matrices(char *matrix, int level) {
if(level == 16) {
print_matrix(matrix);
}
for(int i = 0; i < 10; ++i) {
matrix[level] = i;
print_all_possible_matrices(matrix, level + 1);
}
}
You would use this in the following way:
int main() {
char matrix[16];
print_all_possible_matrices(matrix, 0);
}
But this will take really loooong time to complete.

Related

Recurrence relation for a variant of knapsack problem?

I am finding it difficult to understand two specific implementations which solve this problem on codeforces link.
I understand this is similar to the knapsack problem. However when i solved it myself, i was not aware of the algorithm. I solved it from my own understanding of dynamic programming. My idea is to regard the remaining length of the ribbon as the next state. Here's my code
#include<iostream>
using namespace std;
int main(){
int n,res1=0,res2,x=0;
int a,b,c;
cin >> n >> a >> b >> c;
for(int i=0;i <= n/a; i++){
res2 = -20000;
for(int j=0; j <= (n-(a*i))/b; j++){
x = (n - (a*i) - (b*j));
res2=max(res2,(j + ((x % c) ? -10000 : x/c)));
}
res1=max(res1,i+res2);
}
cout << res1 << endl;
return 0;
Implementation 1:
1 #include <bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int f[4005],n,a,i,j;
6 fill(f+1,f+4005,-1e9);
7 cin>>n;
8 for(;cin>>a;)
9 for(i=a;i<=n;i++)
10 f[i]=max(f[i],f[i-a]+1);
11 cout<<f[n];
12 }
Implementation 2:
1 #include <bits/stdc++.h>
2 int n, a, b, c, ost;
3 std::bitset<4007> mog;
4 main()
5 {
6 std::cin>>n>>a>>b>>c;
7 mog[0]=1;
8 for (int i=1; i<=n; i++)
9 if ((mog=((mog<<a)|(mog<<b)|(mog<<c)))[n])
10 ost=i;
11 std::cout << ost;
12 }
Though i understand the general idea of solving the knapsack problem. I do not have a clear understanding of how lines 8,9,10 in Implementation 1 achieve this. Specifically irrespective of the input values of a,b,c the inner for loop is a single pass over the array for the corresponding value a received.
Similarly, I can see that lines 8,9,10 in implementation 2 does the same thing. But i have no clue at all how this piece of code works.
Please help me understand this. I feel there is some hidden structure to these two solutions which i am not seeing. Thanks in advance.
Implementation 1
This is quite straightforward implementation of dynamic programming.
Outer loop just goes through three values: a, b, and c
8 for(;cin>>a;)
Inner loop visits every element of an array and updates current best known number of cuts for given ribbon length.
9 for(i=a;i<=n;i++)
10 f[i]=max(f[i],f[i-a]+1);
Implementation 2
I don't think that it can be called dynamic programming, but the trick is quite neat.
It allocates array of bits with length equal to max n. Then sets one bit on the left. It means, that ribbon with length of 0 is a valid solution.
On each iteration algorithm shifts given array to the left by a, b, and c. Result of each such shift can be viewed as the new valid sizes of ribbon. By oring result of all 3 shifts, we get all valid sizes after i'th cut. If n'th bit set we know ribbon of size n can be cut i times without remainder.
n = 10
a = 2
b = 3
c = 5
i=1:
0|0000000001 // mog
0|0000000100 // mog<<a
0|0000001000 // mog<<b
0|0000100000 // mog<<c
0|0000101100 // mog=(mog<<a)|(mog<<b)|(mog<<c)
^ here is a bit checked in 'if' statement '(mog=(...))[n]'
i=2:
0|0000101100 // mog
0|0010110000 // mog<<a
0|0101100000 // mog<<b
1|0110000000 // mog<<c // here we have solution with two pieces of size 5
1|0111110000 // (mog<<a)|(mog<<b)|(mog<<c)
^ now bit set, so we have a solution
We know that there is exactly i cuts at that point, so we set ost=i. But we found the worst solution, we have to keep going until we are sure that there is no more solutions.
Eventually we will reach this state:
i=5:
1|1100000000 // mog
1|0000000000 // mog<<a // 5 pieces of size 2
0|0000000000 // mog<<b
0|0000000000 // mog<<c
1|0000000000 // (mog<<a)|(mog<<b)|(mog<<c)
Here it is the last time when bit at position n will be set. So we will set ost=5 and will do some more iterations.
Algorithm uses n as upper bound of possible cuts, but it's obvious that this bound can be improved. For example n / min({a,b,c}) should be sufficient.

how to find consecutive numbers in a sequence

im trying to a write a program that accepts 10 random integers and checks whether there are three consecutive numbers in the sequence or not.The consecutive numbers can be in ascending or descending order.
here are some examples to help you understand better:
order. Examples:
2 9 8 3 20 15 9 6 4 24
Yes, 2 3 and 4 are consecutive
16 21 3 8 20 6 3 9 12 19
Yes, 21 20 and 19 are consecutive
I can't figure out whats wrong with my code.
here is my code so far:
#include <iostream>
using namespace std;
int main()
{
int a[10];
int i,n;
int count=0;
cout << "Enter 10 numbers between 1 and 25" << endl;
for (i = 0; i < 10; i++)
{ cin >> a[i];
}
for (n=0; n<10; n++)
{
for (i=1; i<10; i++)
{
if (a[i]==a[n]+1)
{cout<<endl<<a[i]<<endl;
count++;}
}
}
}
Your code is currently O(N2), and to get it to work it'll be O(N3).
I'd rather use an algorithm that's O(N) instead.
Given that you only care about 25 values, you can start with a 32-bit word, and set the bit in that word corresponding to each number that was entered (e.g., word |= 1 << input_number;).
Then take a value of 7 (which is three consecutive bits set) and test it at the possible bit positions in that word to see if you have three consecutive bits set anywhere in the word. If so, the position at which they're set tells you what three consecutive numbers you've found. If not, then there weren't three consecutive numbers in the input.
for (int i=0; i<32-3; i++) {
int mask = 7 << i;
if (word & mask == mask)
// three consecutive bits set -> input contained i, i+1 and i+2
}
Your logic is wrong. What your current code does is that it checks if there are any two consecutive integers. To check for three, you should introduce another nested loop. This would make the time complexity O(n^3).
Another possible way to check this is to first sort the array, and then check for consecutive elements. This would make the running time O(nlogn). You can use the inbuilt sort function for sorting.
The algorithm needs to be reworked. As it is, what you are doing is saying:
For each array element x
See if another array element is x+1
print out the array element that is x+1
Stick in more cout lines to see what is going on, like
if (a[i]==a[n]+1)
{cout<<endl<<a[n]<<","<<a[i]<<endl;
count++;}
A possible, although slow, algorithm would be
For each array element x
See if another array element is x+1
See if another array element is x+2
print out x, x+1, and x+2

algorithm that does not turn back and selects only one solution [duplicate]

This question already has an answer here:
backtracking select the best solution
(1 answer)
Closed 9 years ago.
for example, have a 4x4 array of integers, I need to select one number from each row such that each selected number is in a different column and the sum of the selected numbers is as low as possible. The grid in question looks like this:
1 2 3 1
2 3 1 3
2 2 1 2
3 4 1 9
My program returns this answer:
1* 2 3 1
2 3* 1 3
2 2 1* 2
3 4 1 9*
but the best solution is:
1 2 3 1*
2 3 1* 3
2* 2 1 2
3 1* 1 9
What do I need to change in my function?
struct r{
bool moze;
int quantity;
};
int ff,m1;
bool check(int n,r **tab, int k)
{
for(int i=0;i<n;i++){
if(tab[k][i].moze==true || tab[i][ff].moze==true)
return false;
}
return true;
}
bool back(int n, r ** tab, int k){
for(int i=0;i<n;i++){
if (check(n,tab,k)){
tab[k][i].moze=true;
if (k==n-1)
{
for(int j=0;j<n;j++)
{
for(int c=0;c<n;c++)
{
if(tab[j][k].moze==true)
cout<<tab[j][i].quantity;
}
}
return true;
}
if (back(n,tab,k+1))
return true;
else
tab[k][i].moze=false;
}
}
return false;
}
how to fix my functions??
function mark(r, c, available):
for each element in [r][]:
mark available
for each element in [][c]:
mark available
function backtrack(table, temp, r, c, sum):
check if sum is solution
for row i in table:
if temp[i][0] is not available go to next row
for column j in table:
if temp[i][j] is available:
mark(i, j, not available)
backtrack(table, temp, i, j, sum+table[i][j])
mark(i, j, available again)
I have a pseudocode but I can not put it in my function,could someone help me, can not help himself
Since this is just a small array, you can bruteforce (there is 4!=24 possibilities) and just take the best one
This function give you the minimum sum, it is easy to adapt the code if you also need the selected elements.
Note that INF is suppose to be big, and M is you given 4x4 array.
int aux(){
std::vector<int> t(4);
for(int i=0;i<4;++i)
t[i]=i;
int mini=INF;
do{
int tmp=0;
for(int i=0;i<4;++i)
tmp+=M[i][t[i]];
mini=std::min(mini, tmp);
}while(std::next_permutation(t.begin(), t.end()));
return mini;
}
Currently your function just returns the first result it finds.
You need to, instead of your 2 return statements, just record the best result as you go.
I won't write the code for you, as you would learn more by figuring it out yourself, but here's 2 hints to get you started:
You may want to store the best result outside of the function, rather than passing it around.
To store the best result, you'll have to store all the indices of the values you selected, not simply the resulting sum.
I hope that helps a bit.

Getting rid of non-unique entries in an adjacency list

I'm currently working on a project for my upper-level C++ class, and we are building a program that makes a maze, then solves it, the makes a PNG of said maze. Pretty cool stuff. Anyways, I'm current on the bit where I need to make the maze.
My program makes valid mazes just fine, but I have to make each number output unique. The output just spits out two indicies in a 2d matrix that have walls between them, sample output for a 3X4 maze is as follows:
rjeffor1:hydra20 ~/cs302/labs/lab5> ./mazemake 3 4 <- 9:49AM
1 2
1 5
2 1
2 3
3 2
5 1
5 9
6 7
7 6
8 9
9 8
9 5
However, my last problem is that I need to get rid of duplicate walls, for example 1 2 and 2 1. EDIT: and by this I mean just get rid of the 2 1, I still need the wall and therefore the 1 2.
Here is my function in which I attempt to fix the problem:
void aL::make_unique()
{
vector<int>::iterator it, it0;
//need to iterate thru all but last index
for (int i=0; i<(int)adjList.size()-1; i++) {
for (int j=0; j<(int)adjList.size(); j++) {
//find it
if (i!=j) {
it0 = std::find(adjList[i].begin(), adjList[i].end(), j);
it = std::find(adjList[j].begin(), adjList[j].end(), i);
if (it!=adjList[j].end() && it!=adjList[j].end())
//erase it if anything is there
adjList[j].erase(it);
}
}
}
}
Help is appreciated, my brain is so done at this point
EDIT: here is how I populate the adjancency lists, based on indicies directly left right above and below each index
aL::aL (const int &rows, const int &cols)
{
adjList.resize(rows*cols);
//run thru and figure out where indicies AREN'T
//to fill in their adjacency list
for (int i=0; i<(int)adjList.size(); i++) {
//if not on the left edge
if (i%cols!=0)
adjList[i].push_back(i-1);
//not on the right edge
if ((i+1)%cols!=0)
adjList[i].push_back(i+1);
//not on the top edge
if (i>=cols)
adjList[i].push_back(i-cols);
//not on the bottom edge
if (i<(rows*cols)-cols)
adjList[i].push_back(i+cols);
}
}
You could remove the need to post-process and make it unique at the end if you check as you are adding to your list. Don't add "a b" if "b a" is already there.

possible combinations and loops

i have to make all possible combinations of a 2d array..for e.g. if i have a array of 4x3 ...i m using 4 loops,all runs up to 3.. to get all combinations...
for.e.g if i have a 4x3 array as given below..
1 2 3
4 5 6
7 8 9
10 11 12
i will have to make combinations like
1,4,7,10
1,4,7,11
1,4,7,12
1,4,8,10
1,4,8,11
1,4,8,12
1,4,9,10
1,4,9,11
1,4,9,12
1,5,8,10
1,5,8,11
1,5,8,12
...........
and so on....
in short all such combinations...the max number of possible combinations in this case will be 3 power 4....and if i have a array of nxm then maximum combinations will be m power n....can any one help creating it....i want help to solve it in generic .....i think recursive function shall be used...as i don't know the no of loop...it will be known during run time...
void buildArray(vector <int> build, vector< vector <int> > &arrays)
{
int position = build.size();
if (position == arrays.size()) { /* current build is one of the solutions*/}
else {
for (int i = 0; i < arrays[position].size(); i++)
{
build.push_back(arrays[position][i]);
buildArray(build, arrays);
build.pop_back();
}
}
}