第一个程序,计算所有的交点,并输出,输出格式是每行都是 a,b,c,d,e,f,g,h[i,j,s,t] 其中前面8个数表示这个交点是 a+bZ+cZ^2+dZ^3+eZ^4+fZ^5+gZ^6+hZ^7 后面四个数表示这个点是直线Z^i Z^j 和 直线Z^s Z^t的交点。 #include <stdio.h> #include <process.h> __int64 factor(__int64 a,__int64 b){ if(b==0)return a; else return factor(b,a%b); } class Q{ __int64 _up; __int64 _down; void Normalize(){ __int64 fac=factor(_up,_down); _down/=fac; _up/=fac; if(_down<0){ _down=-_down; _up=-_up; } } public: Q():_up(0),_down(1){} Q(__int64 up,__int64 down):_up(up),_down(down){} Q(__int64 x):_up(x),_down(1){} Q& operator+=(const Q& x); Q& operator-=(const Q& x); Q& operator*=(const Q& x); Q& operator/=(const Q& x); Q operator-()const{Q tmp=*this;tmp._up=-_up;return tmp;} Q operator+(const Q& x)const{Q tmp=*this;tmp+=x;return tmp;} Q operator-(const Q& x)const{Q tmp=*this;tmp-=x;return tmp;} Q operator*(const Q& x)const{Q tmp=*this;tmp*=x;return tmp;} Q operator/(const Q& x)const{Q tmp=*this;tmp/=x;return tmp;} bool iszero()const{return _up==0;} bool operator==(const Q& x)const{return _up==x._up&&_down==x._down;} void output()const{if(_down==1)printf("% 4I64d",_up);else printf("% 2I64d/%I64d",_up,_down);} }; Q& Q::operator +=(const Q& x){ _up=_up*x._down+_down*x._up; _down*=x._down; Normalize(); return *this; } Q& Q::operator -=(const Q& x){ _up=_up*x._down-_down*x._up; _down*=x._down; Normalize(); return *this; } Q& Q::operator *=(const Q& x){ _up*=x._up; _down*=x._down; Normalize(); return *this; } Q& Q::operator /=(const Q& x){ _up*=x._down; _down*=x._up; Normalize(); return *this; } Q mod[9]={Q(1),Q(1),Q(0),Q(-1),Q(-1),Q(-1),Q(0),Q(1),Q(1)}; void Mod(Q a[15]){ int i,j; for(i=14;i>=8;i--){ Q divider=a[ i ]; for(j=0;j<=8;j++){ a[i-j]-=divider*mod[8-j]; } } } void Dump(const Q M[15][15], const Q b[15]){ int i,j; printf("//n//n"); for(i=0;i<15;i++){ for(j=0;j<14;j++){ M[j][ i ].output(); printf(","); } M[j][ i ].output(); printf("="); b[ i ].output(); printf("//n"); } } void SolveEquation(Q M[8][8],Q b[15]){ int i,j,k; for(i=0;i<8;i++){ // Dump(M,b); for(j=i;j<8;j++) if(!M[ i ][j].iszero())break; if(j!=i){ if(j>=8){ printf("There/'s no inverse for the matrix//n"); exit(-1); } for(k=0;k<8;k++){ Q tmp=M[k][ i ]; M[k][ i ]=M[k][j]; M[k][j]=tmp; } Q tmp=b[ i ]; b[ i ]=b[j]; b[j]=tmp; } Q divider=M[ i ][ i ]; for(j=i;j<8;j++)M[j][ i ]/=divider; b[ i ]/=divider; for(j=0;j<8;j++){ if(j==i)continue; Q mult=M[ i ][j]; for(k=i;k<8;k++)M[k][j]-=mult*M[k][ i ]; b[j]-=mult*b[ i ]; } } }
void Inverse(const Q a[15], Q b[15]){ Q M[8][8]; Q tmp[15]; int i,j; for(i=0;i<8;i++){ for(j=0;j<15;j++)tmp[j]=Q(0); for(j=0;j<8;j++)tmp[i+j]=a[j]; Mod(tmp); for(j=0;j<8;j++){ M[ i ][j]=tmp[j]; } } b[0]=Q(1); for(i=1;i<15;i++)b[ i ]=Q(0); SolveEquation(M,b); } void Multiple(const Q a[15], const Q b[15], Q c[15]){ int i,j; for(i=0;i<15;i++)c=Q(0); for(i=0;i<15;i++)for(j=0;j<15;j++){ if(i+j<15){ c[i+j]+=a[ i ]*b[ j ]; }else{ c[i+j-15]-=a[ i ]*b[ j ]; } } Mod(c); } void Output(const Q r[15],int i,int j,int s,int k){ int u; for(u=0;u<7;u++){ r[u].output(); printf(","); } r[u].output(); printf("[%d,%d,%d,%d]//n",i,j,s,k); } #define INC(z, x) do{// int tmp=(x)%30;if(tmp<0)tmp+=30;// if(tmp<15)(z)[tmp]+=Q(1);// else (z)[tmp-15]-=Q(1);// }while(0) #define DEC(z, x) do{// int tmp=(x)%30;if(tmp<0)tmp+=30;// if(tmp<15)(z)[tmp]-=Q(1);// else (z)[tmp-15]+=Q(1);// }while(0) void Find(int i,int j,int s,int t){ int k; // printf("%d %d %d %d//n",i,j,s,t); Q delta[15],invdelta[15],r[15]; for(k=0;k<15;k++){ delta[k]=0; } INC(delta,j-t);DEC(delta,i-t);DEC(delta,j-s);INC(delta,i-s); DEC(delta,t-j);INC(delta,t-i);INC(delta,s-j);DEC(delta,s-i); Mod(delta); Inverse(delta,invdelta); for(k=0;k<15;k++)delta[k]=0; INC(delta,i-j+s);DEC(delta,i-j+t);DEC(delta,-i+j+s);INC(delta,-i+j+t); INC(delta,j+s-t);DEC(delta,i+s-t);DEC(delta,j-s+t);INC(delta,i-s+t); Mod(delta); Multiple(invdelta,delta,r); Output(r,i,j,s,t); } int main(){ int i,j,s,t; for(i=0;i<30;i++)for(s=i+1;s<30;s++)for(j=s+1;j<30;j++)for(t=j+1;t<30;t++){ Find(i,j,s,t); } }
|
最后计算出来是21480个区域。 计算公式是Sum{(d(i)-1), d(i)是第i个交点经过的对角线数目}+1+L, L是对角线的数目。 这里c30.sort.txt是上面的程序的输出结果排序后的结果。 #include <stdio.h> #include <string.h> #define MAXSIZE 100 struct Intersect{ int i,j,s,t; }Backup[MAXSIZE]; struct Points{ int x,y; }Tmp[MAXSIZE]; int DumpPoints(FILE *out, char *result,int lcount) { int c,i,j; fprintf(out,"%s[",result); for(i=0,c=0;i<lcount;i++){ int x,y; x=Backup[ i ].i;y=Backup[ i].j; for(j=0;j<c;j++){ if(Tmp[j].x==x&&Tmp[j].y==y)break; } if(j==c){ Tmp[j].x=x;Tmp[j].y=y; c++; } x=Backup[ i ].s;y=Backup[ i ].t; for(j=0;j<c;j++){ if(Tmp[j].x==x&&Tmp[j].y==y)break; } if(j==c){ Tmp[j].x=x;Tmp[j].y=y; c++; } } for(i=0;i<c;i++){ fprintf(out,"(%d,%d)",Tmp[ i ].x,Tmp[ i ].y); } fprintf(out,"]//n"); return c; } int main() { char buf[100]; char prev[100]=""; char *p, *q;int lcount=0,scount=0; int i,j,s,t,sum; FILE *in=fopen("c30.sort.txt","r"); FILE *out=fopen("c30.dup.txt","w"); q=prev;sum=0; while(!feof(in)){ fgets(buf,100,in); p=strchr(buf,/'[/'); if(p==NULL)continue; *p=/'//0/';p++; if(strcmp(buf,prev)){//Start new string int c=DumpPoints(out,prev,lcount); if(c>0)sum+=c-1; lcount=0; strcpy(prev,buf); q=prev+(p-buf); strcpy(q,p); scount=0; } sscanf(p,"%d,%d,%d,%d",&i,&j,&s,&t); if(lcount<MAXSIZE){ Backup[lcount].i=i;Backup[lcount].j=j;Backup[lcount].s=s;Backup[lcount].t=t; } if(j-i!=15&&t-s!=15){ scount++; } lcount++; } sum+=DumpPoints(out,prev,lcount)-1; fclose(in); fclose(out); printf("Total %d//n",sum+15*27+1); } |