// Solution to KenKen (assumes all target values > 0) import java.util.*; class Pair { public int r,c; public Pair(int r, int c) { this.r = r; this.c = c; } } public class BKenKen1 { public static int n,m,t,count; public static String op; public static int[][] grid; public static boolean[][] rowused, colused; public static Scanner in; public static Stack sect; public static Stack hold; public static void main(String[] args) { in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); t = in.nextInt(); op = in.next(); grid = new int[n][n]; rowused = new boolean[n][n]; colused = new boolean[n][n]; for (int i = 0; i < n; i++) { Arrays.fill(grid[i],-1); Arrays.fill(rowused[i],false); Arrays.fill(colused[i],false); } sect = new Stack(); hold = new Stack(); for (int i = 0; i < m; i++) { int r = in.nextInt(); int c = in.nextInt(); sect.push(new Pair(r-1,c-1)); grid[r-1][c-1] = 0; } /* System.out.println("Case " + casenum + ":"); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { System.out.printf("%2d",grid[i][j]); } System.out.println(); } */ count = 0; switch (op.charAt(0)) { case '+': solveplus(); break; case '-': solveminus(); break; case '*': solvestar(); break; case '/': solvediv(); break; default: System.out.println("****ERROR: op = " + op); } System.out.println(count); } public static void solveplus() { // Base case--we just placed the last number: if (sect.empty()) { if (t==0) { count++; /* // DEBUG: System.out.println("Solution:"); for (Pair x:hold) { System.out.println(x.r+","+x.c+": "+grid[x.r][x.c]); } */ } return; } // Get next unfilled cell and fill it in all possible ways: Pair p = sect.pop(); hold.push(p); for (int i = 1; i <= n; i++) { // Make sure sum is still achievable: if (i > t) break; // Make sure row constraint is not violated: if (rowused[p.r][i-1]) continue; // Make sure col constraint is not violated: if (colused[p.c][i-1]) continue; t = t-i; rowused[p.r][i-1] = true; colused[p.c][i-1] = true; int temp = grid[p.r][p.c]; grid[p.r][p.c] = i; solveplus(); t = t+i; rowused[p.r][i-1] = false; colused[p.c][i-1] = false; grid[p.r][p.c] = temp; } hold.pop(); sect.push(p); } public static void solvestar() { // Base case--we just placed the last number: if (sect.empty()) { if (t == 1) { count++; /* // DEBUG: System.out.println("Solution:"); for (Pair x:hold) { System.out.println(x.r+","+x.c+": "+grid[x.r][x.c]); } */ } return; } // Get next unfilled cell and fill it in all possible ways: Pair p = sect.pop(); hold.push(p); for (int i = 1; i <= n; i++) { // Make sure product is still achievable: if (i > t) break; // Make sure i is a divisor of t: if (t%i != 0) continue; // Make sure row constraint is not violated: if (rowused[p.r][i-1]) continue; // Make sure col constraint is not violated: if (colused[p.c][i-1]) continue; t = t/i; rowused[p.r][i-1] = true; colused[p.c][i-1] = true; int temp = grid[p.r][p.c]; grid[p.r][p.c] = i; solvestar(); t = t*i; rowused[p.r][i-1] = false; colused[p.c][i-1] = false; grid[p.r][p.c] = temp; } hold.pop(); sect.push(p); } public static void solveminus() { // solve cases where first < second, double count. Assume no "zero" // target. for (int i = 1; i < n; i++) { if (t+i <= n) count+=2; else break; } return; } public static void solvediv() { // solve cases where first < second, double count. Assume no "one" // target (since values must be distinct). for (int i = 1; i < Math.min(t*i,n); i++) { if (t*i <= n) count+=2; else break; } return; } }