Форум умных людей

Задачи и головоломки => Для программистов => Тема начата: Michael от Январь 07, 2013, 20:07:13



Название: Треугольное дерево 2
Отправлено: Michael от Январь 07, 2013, 20:07:13
Пусть у нас есть треугольник из точек, аналогичный тем, что на рисунке.

(http://www.likebook.ru/store/pictures/182/182492/3.png)

На верхнем, первом, ярусе у него одна точка, на втором - две точки, на энном - эн точек. Мы хотим соединить эти точки отрезками по следующим правилам:

1) Каждая точка, кроме корневой (единственной точки первого яруса), может соединяться с нулём, либо с одной точкой предыдущего яруса.
2) Каждая точка может соединяться с нулём, одной, либо двумя точками следующего яруса, причём лишь с ближайшими (k-я точка на n-м ярусе может быть соединина лишь с k-й и (k+1)-й точками на (n+1)-м ярусе).
3) Если точка соединена с нулём точек предыдущего яруса., то она соединена с нулём точек следующего яруса.
4) Никаких соединений, кроме предусмотренных правилами 1),2),3) быть не должно.

Получившийся граф (он, кстати, будет бинарным деревом) мы назовём треугольным деревом порядка N, где N - количество ярусов в нашем точечном треугольнике.

a) Сколько существует различных треугольных деревьев порядка 13?
b) Кто сможет решить задачу для наибольшего порядка > 13?


Задача скопирована с задачи Sirionа
Треугольное дерево (http://nazva.net/forum/index.php/topic,8109.0.html)
Изменено условиe 1)
добавлено условие 3)
добавлен вопрос б)



Название: Re: Треугольное дерево 2
Отправлено: zhekas от Январь 07, 2013, 21:22:31
Опять же к программированию эта задача не имеет ни какого отношения
Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 08, 2013, 07:24:51
Опять же к программированию эта задача не имеет ни какого отношения
Показать скрытый текст
zhekas, вы правы. Я решал одну задачу, а сформулировал другую. Уже исправил, надеюсь на этот раз без ошибок.


Название: Re: Треугольное дерево 2
Отправлено: moonlight от Январь 11, 2013, 15:37:24
3=21
4=196
5=3693
6=150108
7=13615289
8=2792613972
9=1301937665561
10=1382746649587508
11=3348885190425061961
12=18503428445148136202924
Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: moonlight от Январь 11, 2013, 18:37:41
исправил


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 11, 2013, 21:27:51
moonlight, всё верно!


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 14, 2013, 03:51:05
16 = Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 14, 2013, 08:05:53
16 = Показать скрытый текст
отрицательное что ли?  :crazy:


Название: Re: Треугольное дерево 2
Отправлено: moonlight от Январь 14, 2013, 09:56:34
17=Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 14, 2013, 18:16:03
А у меня уже все чётные цифры посчитались для 18 )))

18=**6****2'6*24**4*6'*8*68*8*2'*80880*0*'*800*08*6'**68866*2


Название: Re: Треугольное дерево 2
Отправлено: семеныч от Январь 14, 2013, 18:24:14
и чем ваше цифроблудство отличается от моего?? :crazy:


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 15, 2013, 04:37:52
и чем ваше цифроблудство отличается от моего?? :crazy:
примерно тем же, чем состязание в скорости плавания отличается от поиска смешных ракушек в прибрежном песке


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 16, 2013, 11:53:56
а чего это все дружно прекратили вычисления?


Название: Re: Треугольное дерево 2
Отправлено: семеныч от Январь 16, 2013, 12:18:39
ну да :)

пора же померяться - у кого длиннее :crazy:


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 16, 2013, 13:55:16
вот-вот, только линейку достанешь...


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 16, 2013, 15:32:31
 
а чего это все дружно прекратили вычисления?
Ждём когда посчитаются нечётные цифры для 18 :)


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 17, 2013, 07:58:45
ну а чо 19 не выкладываете?
или вы все жертвы моды и вместо нормальных компьютеров у вас имеются только карманные пародии на эвм?


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 19, 2013, 16:00:56
чота всё затихло...
Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 20, 2013, 05:20:11
moonlight, iPhonograph, здорово!  :beer:У меня пока только 16, но хочу попробовать получить 23. Если получится, скажу. Если не получится, тоже скажу.  iPhonograph, у вас скорость какая-то запредельная.


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 20, 2013, 08:44:50
ок, ждём)))
кто вычислит 23 раньше всех - получит спасибку )))
для проверки правильности результата - вот чётные цифры
Показать скрытый текст


Название: Re: Треугольное дерево 2
Отправлено: iPhonograph от Январь 20, 2013, 08:47:58
iPhonograph, у вас скорость какая-то запредельная.
да я понимаю, на что вы намекаете
типа, кто будет писать случайные цифры и выдавать их за результат, получит по наглой рыжей морде )))
могу дать исходник программы, чтобы вы запустили её на своём компе


Название: Re: Треугольное дерево 2
Отправлено: Michael от Январь 20, 2013, 11:58:56
Да ну, iPhonograph, о чём вы говорите?   :bad3:
У нас джентльменам верят на слово!  :beer: тут то мне карта и поперла(шутка)  :laugh:
Тем более, что проверить отдельные цифры можно и без памяти. :read:
Но у меня и в мыслях этого не было. :no2: 
Я не про скорость написания, а про ваш секундомер. Я намекал на то что у вас должен быть классный алгоритм.  :bravo2:
Когда всё кончится, конечно, интересно будет посмотреть.  :whiteflag:
А пока не надо.  :-X


Название: Re: Треугольное дерево 2
Отправлено: or0ez от Январь 08, 2020, 12:58:13
программа на С
Код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 16
#define u16 unsigned short
#define u32 unsigned
#define max 20

typedef struct{u16 q[N];short nz;}u16N;
typedef struct{u16N u0,u1;}u16N2;
typedef struct{int n,g;}int2;
typedef struct{int len;int2* p;}int2arr;

u16N new16N(){u16N a;for(int i=0;i<N;i++)a.q[i]=0;a.nz=0;return a;}

int nZ(u16 q[N]){int cnt=N;for(int i=N-1;i>=0;i--)if(q[i])break;else cnt--;return cnt;}

u16N toU16N(u32 n){u16N a=new16N();a.q[0]=n;a.q[1]=(n>>16);a.nz=a.q[1]?2:(a.q[0]?1:0);return a;}

u16N sum(u16N a,u16N b){
    int m=a.nz>=b.nz?a.nz:b.nz;
    u16N s=new16N();
    u32 c=0;
    for(int i=0;i<m;i++){u32 t=c+a.q[i]+b.q[i];s.q[i]=t;c=t>>16;}
    if(c&&m<N)s.q[m]=1;
    s.nz=nZ(s.q);
    return s;
}

int cmp(u16N a, u16N b){
    int s=a.nz-b.nz;
    if(s)return s;
    for(int i=a.nz-1;i>=0;i--)if(s=a.q[i]-b.q[i])return s;
    return 0;
}

u16N inv(u16N a){
    u16N b;
    for(int i=0;i<N;i++)
    b.q[i]=~a.q[i];
    b.nz=nZ(b.q);
    return b;
}

u16N subt(u16N a, u16N b){return sum(a,sum(inv(b),toU16N(1)));}

u16N shL0(u16N a,int n){
    u16N b=new16N();
    u16 c=0;
    for(int i=0;i<a.nz;i++){u32 r=c|((u32)a.q[i]<<n);b.q[i]=r;c=r>>16;}
    if(a.nz<N)b.q[a.nz]=c;
    b.nz=nZ(b.q);
    return b;
}

u16N shL(u16N a,int n){
    u16N b=shL0(a,n&0xf);
    int n1=n>>4;
    if(n1)for(int i=a.nz;i>=0;i--){int j=i+n1;if(j<N)b.q[j]=b.q[i];if(i<N)b.q[i]=0;}
    b.nz=nZ(b.q);
    return b;
}

u16N shR(u16N a){
    u16N b=new16N();
    for(int i=a.nz-1;i>=0;i--){u32 u=(i==a.nz-1?0:a.q[i+1]);u32 w=(u<<16)|a.q[i];b.q[i]=(w>>1);}
    b.nz=nZ(b.q);
    return b;
}

int max1(u16N a){
    int k=-1;
    if(a.nz){for(int i=15;i>=0;i--)if((a.q[a.nz-1]>>i)&1){k=i;break;}k+=(a.nz-1)<<4;}
    return k;
}

u16N2 div2(u16N a,u16N b){
    u16N2 res;
    res.u0=new16N();
    int d=max1(a)-max1(b);
    if(d<0){res.u1=a;return res;}
    u16N bb=shL(b,d);
    if(cmp(a,bb)>=0){res.u0=toU16N(1);a=subt(a,bb);}
    while(cmp(bb,b)){
        bb=shR(bb);
        res.u0=shL(res.u0,1);
        int k=cmp(a,bb);
        if(k>=0){if(!res.u0.nz)res.u0.nz=1;res.u0.q[0]|=1;a=subt(a,bb);}
    }
    res.u1=a;
    return res;
}

void show(u16N a){
    if(!a.nz){printf("0\n");return;}
    int d[(int)(N*1.25)+1];
    int cnt=0;
    u16N b=toU16N(1000000);
    while(a.nz){u16N2 c=div2(a,b);d[++cnt-1]=c.u1.q[0]+((u32)c.u1.q[1]<<16);a=c.u0;}
    printf("%d",d[cnt-1]);
    for(int i=cnt-2;i>=0;i--)printf(" %06d",d[i]);
}

int2arr f(int n,int l){
    int q[max-1];
    int cnt=0;
    for(int i=0;i<l;i++)
        if((n>>i)&1)q[++cnt-1]=i;
    int q1[max],s[max];
    int cnt1=0;
    for(int i=0;i<cnt;i++)
        if(i==0){q1[0]=q[0];q1[1]=q[0]+1;s[0]=s[1]=1;cnt1=2;}
        else{
            if(q[i]==q1[cnt1-1])s[cnt1-1]++;
            else{q1[++cnt1-1]=q[i];s[cnt1-1]=1;}
            q1[++cnt1-1]=q[i]+1;s[cnt1-1]=1;
        }
    int2arr a;
    a.len=1<<cnt1;a.p=(int2*)malloc(a.len*sizeof(int2));
    for(int i=0;i<a.len;i++){
        int g=0;int n=0;
        for(int j=0;j<cnt1;j++){int k=(i>>j)&1;n|=k<<q1[j];if(k&&s[j]>1)g++;}
        a.p[i].n=n;a.p[i].g=g;
    }
    return a;
}

char* hms(char* time){
    char* hms=(char*)malloc(9*sizeof(char));
    for(int i=0;i<8;i++)hms[i]=time[i+11];
    hms[8]='\0';
    return hms;
}

int main(){
    printf("max=%d\n\n",max);
    int l=1;
    u16N* m=(u16N*)malloc(2*sizeof(u16N));
    m[0]=toU16N(0);m[1]=toU16N(1);
    while(l<max){
        int size=1<<l;
        int size1=1<<(l+1);
        u16N* m1=(u16N*)malloc(size1*sizeof(u16N));
        for(int i=0;i<size1;i++)m1[i]=new16N();
        for(int i=0;i<size;i++){
            int2arr a=f(i,l);
            for(int j=0;j<a.len;j++)m1[a.p[j].n]=sum(m1[a.p[j].n],shL0(m[i],a.p[j].g));
            free(a.p);
        }
        free(m);m=m1;l++;
        u16N s=new16N();
        for(int i=0;i<size1;i++)s=sum(s,m1[i]);
        int tm=time(0);
        printf("%s",hms(ctime(&tm)));
        printf("%4d = ",l);
        show(s);printf("\n\n");
    }
    free(m);
    return 0;
}


Название: Re: Треугольное дерево 2
Отправлено: or0ez от Январь 12, 2020, 14:15:46
Извиняюсь, в функции main() должно быть не shL0, а shL. Ошибка проявляется на 19, 20.