Cześć,
Mam problem z zadaniem Antytrójkątowe pudełko z 3 etapu OIJ: https://szkopul.edu.pl/problemset/problem/c-iPsg6lceV8Nkkk9Zw1s1iN/site/?key=statement
Udało mi się dostać 25pkt, pierwsze ograniczenie. Napisałem backtracking i sprwadzam wszystkie możliwe pudełka.
Mój kod:
#include <iostream>
#include <vector>
#include <set>
#include <queue>
using namespace std;
bool czy_antytrojkatowe(vector<int>& patyczki)
{
vector<int> spr;
for (int i = 1; i < patyczki.size(); ++i)
{
for (int j = 0; j < patyczki[i]; ++j)
{
spr.push_back(i);
}
}
bool czy_antytrojkotowe_flaga = true;
if (spr.size() <= 2)
{
return true;
}
else
{
int p = -1;
int k = -1;
int l = 0;
for (auto f : spr)
{
if (f != -1)
{
l++;
if (p == -1)
{
p = f;
}
else if (k == -1)
{
k = f;
}
else
{
if (p+k > f)
{
return false;
}
p = k;
k = f;
}
}
}
}
return true;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n = 0;
int m = 0;
int wczytana_liczba = 0;
cin >> n >> m;
int zliczanie[m+1] {0};
for (int i = 0; i < n; ++i)
{
cin >> wczytana_liczba;
zliczanie[wczytana_liczba]++;
}
queue<vector<int>> Q;
set<vector<int>> permutacje;
vector<int> nap;
for (int i = 0; i <= m; ++i)
{
nap.push_back(0);
}
Q.push(nap);
while(!Q.empty())
{
vector<int> sprawdzany = Q.front();
for (int i = 1; i <= m; ++i)
{
sprawdzany[i]++;
auto it = permutacje.find(sprawdzany);
if (sprawdzany[i] <= zliczanie[i] && it == permutacje.end() && czy_antytrojkatowe(sprawdzany) == true) // Mozemy postawic, nie znalezlismy permutacji, jest antytrojkatowe.
{
permutacje.insert(sprawdzany);
Q.push(sprawdzany);
}
sprawdzany[i]--;
}
Q.pop();
}
cout << permutacje.size() << endl;
return 0;
}
Wiem, że pewnie to zadanie polega na zliczaniu a nie generowaniu przypadków.
Ma ktoś pomysł jak rozwiązać to zadanie?
Z góry dziękuję za pomoc!