Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Proof for the problem Harry Potter and the Sorting Hat
- Author: Natalia Bondarenko
- */
- #pragma comment(linker, "/STACK:64000000")
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <vector>
- #include <string>
- #include <map>
- #include <set>
- #include <queue>
- #include <algorithm>
- #include <cmath>
- #include <cassert>
- #include <sstream>
- using namespace std;
- #define forn(i, n) for (int i = 0; i < int(n); i++)
- #define for1(i, n) for (int i = 1; i <= int(n); i++)
- #define forv(i, v) forn(i, v.size())
- #define all(x) x.begin(), x.end()
- #define pb push_back
- #define mp make_pair
- #define COUT_FILE "output.txt"
- #define pi 3.1415926535897932
- typedef pair<int, int> pii;
- typedef long long ll;
- typedef long double ld;
- #define INF 1000000009
- #define NMAX 1000006
- typedef vector<vector<int> > State;
- int n;
- State s[NMAX];
- int prev[NMAX], pval[NMAX];
- vector<int> pr[NMAX];
- vector<vector<int> > seq;
- void rec(vector<int>& v)
- {
- bool finish = false;
- forv(i, v)
- {
- if (v[i] == -1)
- {
- for (int j = 1; j <= 3; j++)
- {
- v[i] = j;
- rec(v);
- }
- break;
- finish = true;
- }
- }
- if (!finish)
- {
- seq.pb(v);
- }
- }
- void gen_seq()
- {
- forn(mask, (1 << 4))
- {
- if (mask == 0) continue;
- vector<int> v;
- v.resize(4);
- forn(i, 4)
- {
- if (mask & (1 << i)) v[i] = 0;
- else v[i] = -1;
- }
- rec(v);
- }
- }
- void init()
- {
- State start;
- vector<int> zero;
- forn(i, 4) zero.pb(0);
- start.pb(zero);
- s[n++] = start;
- gen_seq();
- sort(all(seq));
- }
- vector<int> norm(State& a)
- {
- vector<int> r;
- forn(i, 4) r.pb(0);
- forn(i, 4)
- {
- int mn = INF;
- forv(j, a)
- {
- mn = min(mn, a[j][i]);
- }
- r[i] = mn;
- forv(j, a)
- {
- a[j][i] -= mn;
- }
- }
- sort(all(a));
- a.erase(unique(all(a)), a.end());
- return r;
- }
- int max_size = 0;
- void correct(State b)
- {
- assert(b.size() <= 13);
- max_size = max(max_size, (int)b.size());
- vector<int> s;
- forv(i, b)
- {
- int sum = 0;
- int cnt2 = 0;
- forv(j, b[i])
- {
- sum += b[i][j];
- if (b[i][j] == 2) cnt2++;
- assert(b[i][j] < 3);
- }
- s.pb(sum);
- }
- forv(i, b) assert(s[i] == s[0]);
- }
- void apply(vector<int>& a, vector<int>& v, State& b)
- {
- vector<int> cur;
- cur.resize(4);
- int mn = INF;
- forn(i, 4)
- {
- cur[i] = a[i] + v[i];
- mn = min(cur[i], mn);
- }
- forn(i, 4)
- {
- if (cur[i] == mn)
- {
- a[i]++;
- b.pb(a);
- a[i]--;
- }
- }
- }
- void go(State a, int ind)
- {
- forv(i, seq)
- {
- State b;
- forv(j, a)
- {
- apply(a[j], seq[i], b);
- }
- vector<int> rest = norm(b);
- bool ok = false;
- forn(j, n)
- {
- if (s[j] == b)
- {
- ok = true;
- break;
- }
- }
- if (!ok)
- {
- prev[n] = ind;
- pval[n] = i;
- pr[n] = rest;
- s[n++] = b;
- correct(b);
- }
- }
- }
- void add_letter(int i)
- {
- if (i == 0) printf("G");
- if (i == 1) printf("H");
- if (i == 2) printf("R");
- if (i == 3) printf("S");
- }
- void build_test(int i)
- {
- vector<int> s1, s2;
- vector<vector<int> > rest;
- while (i > 0)
- {
- s1.pb(prev[i]);
- s2.pb(pval[i]);
- rest.pb(pr[i]);
- i = prev[i];
- }
- reverse(all(s1));
- reverse(all(s2));
- reverse(all(rest));
- vector<int> a;
- forn(i, 4) a.pb(0);
- forv(j, s2)
- {
- vector<int> cur = seq[s2[j]];
- while (a != cur)
- {
- bool ok = false;
- forv(i, cur)
- {
- if (a[i] < cur[i])
- {
- a[i]++;
- add_letter(i);
- ok = true;
- }
- }
- if (!ok)
- {
- forv(i, cur)
- {
- if (a[i] == 0)
- {
- a[i]++;
- add_letter(i);
- }
- }
- }
- //norm
- int mn = INF;
- forv(i, a) mn = min(mn, a[i]);
- forv(i, a) a[i] -= mn;
- }
- printf("?");
- forv(i, a) a[i] += rest[j][i];
- int mn = INF;
- forv(i, a) mn = min(mn, a[i]);
- forv(i, a) a[i] -= mn;
- }
- }
- int main()
- {
- freopen(COUT_FILE, "wt", stdout);
- init();
- forn(i, n)
- {
- go(s[i], i);
- cerr << n << endl;
- }
- /*
- forn(i, n)
- {
- if (s[i].size() == 13)
- {
- build_test(i);
- break;
- }
- }
- */
- vector<vector<int> > v;
- forn(i, n)
- {
- forv(j, s[i])
- {
- v.pb(s[i][j]);
- }
- }
- sort(all(v));
- v.erase(unique(all(v)), v.end());
- forv(i, v)
- {
- forv(j, v[i])
- {
- cout << v[i][j] << " ";
- }
- cout << endl;
- }
- cout << max_size << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement