//dennismv #include #include #include #include using namespace std; #define FOR(i,n) for (int i=0;i<(int)n;i++) #define FORN(i,a,b) for (int i=a;i<=b;i++) const int MAX=10; int primes[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199}; const int numPrimes=46; int storedGrid[MAX][MAX]; bool gridIsStored; int minSum; bool checkPlacement(int grid[][MAX],vector &isPrime,int row,int col) { int center=grid[row][col]; if (row-1>=0 && !isPrime[center+grid[row-1][col]]) return false; if (col-1>=0 && !isPrime[center+grid[row][col-1]]) return false; return true; } bool optimalSum(int grid[][MAX],int g) { int sum=0; FOR(i,g)FOR(j,g)sum+=grid[i][j]; int optimalSum=g*g*(1+g*g)/2; return (sum==optimalSum); } void showGrid(int grid[][MAX],int g,int count) { cout<<"Matt, here is puzzle #"<fieldWidth) fieldWidth=grid[i][j]; fieldWidth=(int)floor(log((double)fieldWidth)/log((double)10)+1); FOR(i,g) { cout< &isPrime,int gridPlace=0) { if (gridPlace==g*g) { if (optimalSum(grid,g)) { //cout<<"OPTIMALE!\n"; return true; } if (minGridSum(grid,g)) //found next smallest grid!! { //store grid! //showGrid(grid,g,1); gridIsStored=true; FOR(i,g)FOR(j,g) storedGrid[i][j]=grid[i][j]; } return false; } //stuff int final; if (g>4) final=g*g; else final=2*g*g; FOR(i,final) { if (used[i]) continue; used[i]=true; grid[gridPlace/g][gridPlace%g]=i+1; if (checkPlacement(grid,isPrime,gridPlace/g,gridPlace%g) && placeNext(grid,g,used,isPrime,gridPlace+1)) return true; grid[gridPlace/g][gridPlace%g]=0; used[i]=false; } return false; } int main() { int grid[MAX][MAX]; bool used[MAX*MAX]; //get prime index ready vector isPrime(primes[numPrimes-1]+1); FOR(i,numPrimes) isPrime[primes[i]]=true; int n,count=1,g; while (cin>>g>>n && g!=0) { gridIsStored=false; minSum=300000; //min sum FOR(i,100) used[i]=0; grid[0][0]=n; //place n in top left used[n-1]=true; //and mark it used //place remaining elements if (count>1) cout<