Перебор чисел
- From
- Georgy Plechanov (2:5026/49.33)
- To
- Dmitriy Gerasimenko
- Date
- 2002-07-22T11:30:56Z
- Area
- RU.ALGORITHMS
Прогламаранж, Dmitriy!
22 Июл 02 09:08, Dmitriy Gerasimenko -> Andrey Belyakov:
AB>> Да нет. Обычная force-атака, т.е. перебором.
DG> Слабо верится!
DG> Подробнее о "force-атаках" можно ?. Приведи пример, если есть.
DG> Дмитрий
обычных, Дмитpий, мы не деpжим, но если интеpесно вот тебе умный пеpебоp
(пpога находит кол-во ваpиантов pазбиения шашматной доски nXn на 2-е
идентичные части, пеpевоpоты и отpажения за повоpот не считать)
Да, слабонеpвным пpосьба нажать Дел
* ---===* Здесь будет _Windows Clipboard_ *===--- *
class cm3
{
public:
bool *data; //chess tble
int **dtab; //depend. tabl
bool *idt; //init-zation dep table
int n; //num of el
int side; //side len
int count;
int lna;
int beg ;
bool left;
bool leftz;
bool up;
bool upz;
int ret;
int cmax;
void init(int sd)
{
side=sd;
n=sd*sd/2;
count=0;
lna =1;
data = new bool [n+side+10];
idt =data+n+5;
dtab = new int* [n];
for(int i=0;i<n;i++)
dtab[i] = new int [side];
acttabgen(0);
}
int go(int sd,int max)
{
cmax=max;
init(sd);
return count;
}
bool setbeg()
{
lna=1;
for(int i=0;i<side;i++)
dtab[side-1][i]=-1;
int c=0;
for(int z=0;z<side;z++)
{
if(dtab[side-1][z]!=-1)
continue;
inittable(z);
if(z==side-1)
lna=0;
for(int i=0;i<side;i++)
{
if(idt[i])
dtab[side-1][i]=z;
}
}
lna=side;
return 1;
}
bool inittable(int n)
{
for(int i=0;i<side;i++)
idt[i]=0;
idt[n]=1;
while(itabact());
return 1;
}
bool itabact()
{
bool ret=0;
for(int i=0;i<side;i++)
{
if(idt[i])
{
if(data[i]!=data[side-i-1]&&!idt[side-i-1])
{
idt[side-i-1]=1;
ret=1;
}
else if(i&&data[i]==data[i-1]&&!idt[i-1])
{idt[i-1]=1;
ret=1;
}
else if(i!=side-1&&data[i]==data[i+1]&&!idt[i+1])
{idt[i+1]=1;
ret=1;
}
//if(ret)
// return 1;
}
}
return ret;
}
void gettab(int num)
{
printf("\nvarint -","%ld",q);
printf("\n");
for(int y=0;y<side/2;y++)
{
for(int x=0;x<side;x++)
{
if(!data[(side-x-1)+(side/2-y-1)*side])
printf("0");
else
printf(" ");
}
printf("\n");
}
for(y=0;y<side/2;y++)
{
for(int x=0;x<side;x++)
{
if(data[x+y*side])
printf("0");
else
printf(" ");
}
printf("\n");
}
}
void acttabgen(int gen)
{
if(gen==side)
{
ntab();
return;
}
data[gen]=0;
acttabgen(gen+1);
if(gen==side/2-1||gen==side/2||gen==0)
return;
data[gen]=1;
acttabgen(gen+1);
}
void ntab()
{
setbeg();
act(side);
}
void act(int gen)
{
if(lna<0&&lna+1000>0)
lna=2;
if(count==cmax)
return;
if(gen>side&&!abrute(gen-1))
return;
if(gen==n||ntest(gen-1))
{
if(ltest())
{
count++;
gettab(count);
}
return;
}
data[gen]=1;
act(gen+1);
data[gen]=0;
act(gen+1);
}
bool ntest(int gen)
{
if(gen<side)return 0;
bool z = data[gen-1]
for(int i=gen-side;i<gen;i++)
{
if(data[i]!=z)return 0;
}
for(int i=gen-1;i<n;i++)
{
data[i]=z;
}
return 1;
}
void copytab(int gen)
{
for(int i=0;i<side;i++)
{
dtab[gen][i]=dtab[gen-1][i];
}
}
bool abrute(int gen)
{
copytab(gen);
beg = (gen)%side;
left=0;
leftz=0;
up=0;
upz=0;
setfl(gen);
if(!chfl(gen))//||!qutest(gen))
{
return 0;
}
dtab[gen][beg]=ret;
if(!qutest(gen))
{
return 0;
}
return 1;
}
bool qutest(int gen)
{
bool i1=0;
bool i0=0;
bool c1=0;
bool c0=0;
for(int i=0;i<side;i++)
{
if(dtab[gen][i]==0)
{
if(data[gen+i-side]==0)
c0=1;
else
c1=1;
}
else
{
if(data[gen+i-side]==0)
i0=1;
else
i1=1;
}
if(c1&&c0)
return 1;
}
if((i1&&!c1)||(i0&&!c0))
return 0;
return 1;
}
void setfl(int gen)
{
if(beg&&data[gen]==data[gen-1])
{
left=1;
if(dtab[gen][beg-1]==0)
leftz=1;
}
if(data[gen]==data[gen-side])
{
if(dtab[gen][beg]==0)
upz=1;
up=1;
}
}
bool chfl(int gen)
{
if(up&&left)
{
if(leftz&&upz)
{
ret=0;
}
else if(leftz+upz)
{
repl(dtab[gen][beg-upz],0,gen);
ret =0;
}
else
{
repl(dtab[gen][beg-1],dtab[gen][beg],gen);
ret =dtab[gen][beg];
}
}
else if(left)
{ ret=dtab[gen][beg];
dtab[gen][beg]=dtab[gen][beg-1];
if(!isin(ret,gen))
return 0;
ret=dtab[gen][beg];
}
else if(up)
ret=dtab[gen][beg];
else
{
ret=dtab[gen][beg];
dtab[gen][beg]=lna;
lna++;
if(!isin(ret,gen))
return 0;
ret=lna-1;
}
return 1;
}
void repl(int what,int to,int gen)
{
for(int i=0 ;i<side;i++)
{
if(dtab[gen][i]==what)
dtab[gen][i]=to;
}
}
bool isin(int what,int gen)
{
for(int i=0 ;i<side;i++)
{
if(dtab[gen][i]==what)
break;
}
if(i==side)
return 0;
return 1;
}
bool ltest()
{
for(int i=0;i<side;i++)
{
if(dtab[n-1][i]!=0)
return 0;
}
return 1;
}
};
int main()
{
cm3 c;
c.go(8,-1);
};
* ---===* Здесь был _Windows Clipboard_ *===--- *
--
Зю?
... В подарок каждому сотому читателю мылом ушел своп!
--- написанное выше содержит ошибки
* Origin: np: Era - Divano (Star Profile) (2:5026/49.33)