Cod sursa(job #1702176)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 14 mai 2016 17:28:23
Problema Copii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
/*

#include <bits/stdc++.h>

using namespace std;

const int nmax = 11;

int n , i , j , teams , ans;
int v[nmax+10];
char A[nmax+10];

bool friends[(1<<nmax)+10][(1<<nmax)+10];

void updFriends(int lvl , int a , int b)
{
    if (lvl == n + 1)
    {
        friends[a][b] = 1;
        return;
    }

    if (lvl == i)
        updFriends(lvl + 1 , a ^ (1 << lvl) , b);
    else if (lvl == j)
        updFriends(lvl + 1 , a , b ^ (1 << lvl));
    else
    {
        updFriends(lvl + 1 , a , b);
        updFriends(lvl + 1 , a ^ (1 << lvl) , b);
        updFriends(lvl + 1 , a , b ^ (1 << lvl));
    }
}

void solve(int node)
{
    for (int i = 1; i < teams; ++i)
        if (!friends[v[i]][v[teams]] || !friends[v[teams]][v[i]])
            return;

    if (node > n)
    {
        if (teams >= 2) ans++;
        return;
    }

    /// bit 1 - se alatura la o echipa precedenta
    for (int i = 1; i <= teams; ++i)
    {
        v[i] ^= (1 << node);
        solve(node + 1);
        v[i] ^= (1 << node);
    }

    /// bit 0 - echipa noua
    v[++teams] = (1 << node);
    solve(node + 1);
    v[teams--] = 0;
}

int main()
{
    freopen("copii.in","r",stdin);
    freopen("copii.out","w",stdout);

    scanf("%d\n", &n);

    for (i = 1; i <= n; ++i)
        for (gets(A+1), j = 1; j <= n; ++j)
            if (A[j] == '1')
                updFriends(1 , 0 , 0);

    solve(1);
    printf("%d\n", ans);

    return 0;
}

*/

#include <cstdio>
#include <vector>
#include <set>

using namespace std;

const int Nmax = 11;

int n , i , j , echipe , ways;
int v[Nmax+10];

bool prieteni[(1<<Nmax)+10][(1<<Nmax)+10];

char A[Nmax+10];

void make_friends(int level , int a , int b)
{
    if (level == n + 1)
    {
        prieteni[a][b] = 1;
        return;
    }

    if (level == i)
        make_friends(level + 1 , a ^ (1 << level) , b);
    else if (level == j)
        make_friends(level + 1 , a , b ^ (1 << level));
    else
    {
        make_friends(level + 1 , a , b);
        make_friends(level + 1 , a ^ (1 << level) , b);
        make_friends(level + 1 , a , b ^ (1 << level));
    }
}

void check(int nod)
{
    if (nod <= n)
    {
        /// bit 1 - se alatura la o echipa precedenta
        for (int i = 1; i <= echipe; ++i)
        {
            v[i] ^= (1 << nod);
            check(nod + 1);
            v[i] ^= (1 << nod);
        }

        /// bit 0 - echipa noua
        v[++echipe] = (1 << nod);
        check(nod + 1);
        v[echipe--] = 0;
    }
    else
    {
        if (echipe < 2) return;

        for (int ind = 1; ind <= echipe; ++ind)
            for (int i = 1; i <= echipe; ++i)
                if (i != ind && !prieteni[v[ind]][v[i]])
                    return;

        ++ways;
    }
}

int main()
{
    freopen("copii.in","r",stdin);
    freopen("copii.out","w",stdout);

    scanf("%d\n", &n);

    for (i = 1; i <= n; ++i)
        for (gets(A+1), j = 1; j <= n; ++j)
            if (A[j] == '1')
                make_friends(1 , 0 , 0);

    check(1);

    printf("%d\n", ways);

    return 0;
}