枚舉!很暴力

坑爹的奧數

問題描述

小哼遇到了一道奧數題:
???+???=???,將數字1~9分別填入9個?中使得等式成立的組合共幾種?
注:一個式子中每個數字只能使用一次。並且規定左右如173+286=459 和 286+173=459的形式是同一個組合。

package com.qianwei.chapter3;

public class MathematicalOlympiadTest1 {

	public static void main(String[] args) {
		int[] a = new int[10];
		int[] book = new int[10];
		int count = 0;
		
		for (a[1] = 1; a[1] <= 9; a[1]++)
			for (a[2] = 1; a[2] <= 9; a[2]++)
				for (a[3] = 1; a[3] <= 9; a[3]++)
					for (a[4] = 1; a[4] <= 9; a[4]++)
						for (a[5] = 1; a[5] <= 9; a[5]++)
							for (a[6] = 1; a[6] <= 9; a[6]++)
								for (a[7] = 1; a[7] <= 9; a[7]++)
									for (a[8] = 1; a[8] <= 9; a[8]++)
										for (a[9] = 1; a[9] <= 9; a[9]++)
										{
											//此步不能省
										    for (int i = 1; i <= 9; i++)
												book[i] = 0;
											for (int i = 1; i <= 9; i++)
												book[a[i]] = 1;
											int sum = 0;
											for (int i = 1; i <= 9; i++)
												sum += book[i];
											if (sum == 9 && a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9])
											{
												count++;
												System.out.println(""+a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]);
											}
										}
		System.out.println(count/2);
	}
}

 

若使用全排列的方法做十分簡單,如下所示

package com.qianwei.chapter3;

public class MathematicalOlympiadTest2 {

	static int cnt = 0;
	
	public static void main(String[] args) {
		int[] x = {1,2,3,4,5,6,7,8,9};		
		f(x,0);
		System.out.println(cnt/2);
	}
	
	private static void f(int[] x, int k) {
		if(k>=x.length){
			test(x);
			return;
		}
		
		for(int i=k; i<x.length; i++){
			{int t=x[k]; x[k]=x[i]; x[i]=t;}
			f(x,k+1);
			{int t=x[k]; x[k]=x[i]; x[i]=t;}  
		}
	}
	
	private static void test(int[] x) {
		int a = x[0]*100 + x[1]*10 + x[2];
		int b = x[3]*100 + x[4]*10 + x[5];
		int c = x[6]*100 + x[7]*10 + x[8];
		if (a+b==c)	{
			System.out.println(a+" + "+b+" = "+c);
			cnt++;
		}
	}
}

 

炸彈人

問題描述

小哼最近愛上了“炸彈人”遊戲。你還記得在小霸王遊戲機上的炸彈人嗎?用放置炸彈的方法來消滅敵人。需將畫面上的敵人全部消滅後,並找到隱藏在牆裏的暗門才能過關。
  

現在有一個特殊的關卡如下。你只有一枚炸彈,但是這枚炸彈威力超強(殺傷距離超長,可以消滅殺傷範圍內所有的敵人)。請問在哪裏放置炸彈纔可以消滅最多的敵人呢。
  
我們先將這個地圖模型化。牆用 # 表示。這裏有兩種牆,一種是可以被炸掉的,另外一種是不能被炸掉的。但是由於現在只有一枚炸彈,所以都用 # 表示,炸彈是不能穿牆的。敵人用 G 表示,空地用 . 表示,當然炸彈只能放在空地上。

輸入格式:

第一行2個整數爲n m 表示迷宮的行和列,接下來的n行m列爲地圖。
1<=n,m<=50

輸出格式:

輸出做最多可以消滅的敵人數

樣例 1 :

輸入:
13 13
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.###
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
輸出:
8
package com.qianwei.chapter3;

import java.util.Scanner;

public class Bomberman {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int sum, x, y;
		int p=0, q=0, map=0;
		int n = sc.nextInt();
		int m = sc.nextInt();
		char[][] a = new char[n][m];
		for (int i=0;i<n;i++)
			a[i] = sc.next().toCharArray();
		for (int i=0;i<n;i++) {
			for (int j=0;j<m;j++) {
				if (a[i][j] == '.') {
					sum = 0;
					//由於所給地圖最外圍是一圈圍牆,所以下面試探各個方向都不會出現數組越界
					//向上統計可以消滅的敵人數
					x = i;
					y = j;
					while (a[x][y] != '#') {
						if (a[x][y] == 'G')
							sum++;
						x--;
					}
					
					//向下統計可以消滅的敵人數
					x = i;
					y = j;
					while (a[x][y] != '#') {
						if (a[x][y] == 'G')
							sum++;
						x++;
					}
					
					//向左統計可以消滅的敵人數
					x = i;
					y = j;
					while (a[x][y] != '#') {
						if (a[x][y] == 'G')
							sum++;
						y--;
					}
					
					//向右統計可以消滅的敵人數
					x = i;
					y = j;
					while (a[x][y] != '#') {
						if (a[x][y] == 'G')
							sum++;
						y++;
					}
					
					//更新map的值
					if (sum > map) {
						map = sum;
						p = i;
						q = j;
					}
				}
			}
		}
		System.out.println("將炸彈放置在"+"("+p+","+q+"),"+"最多可以消滅"+map+"個敵人");
		sc.close();
	}
}

 

火柴棍等式

問題描述

給你n根火柴棍,你可以拼出多少個形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整數(若該數非零,則最高位不能是0)。用火柴棍拼數字0-9的拼法如圖所示:

注意:
1. 加號與等號各自需要兩根火柴棍
2. 如果A≠B,則A+B=C與B+A=C視爲不同的等式(A、B、C>=0)
3. n根火柴棍必須全部用上

輸入格式:

只有一行,有一個整數n(n<=24)。

輸出格式:

只有一行,表示能拼成的不同等式的數目。

提示:

NOIP提高組2008

限制:

每個測試點1秒

樣例 1 :

輸入:
14
輸出:
2
說明:
2個等式爲0+1=1和1+0=1。

樣例 2 :

輸入:
18
輸出:
9
說明:
9個等式爲:  0+4=4  0+11=11  1+10=11  2+2=4  2+7=9  4+0=4  7+2=9  10+1=11  11+0=11
package com.qianwei.chapter3;

import java.util.Scanner;

public class Matchstick {

	static int[] f= {6,2,5,5,4,5,6,3,7,6};
	
	public static int fun(int x)
	{
		int num = 0;
		while (x / 10 != 0)
		{
			num += f[x%10];
			x = x/10;
		}
		num += f[x];
		return num;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int sum = 0;
		int m = sc.nextInt();
		 for (int a = 0; a <= 1111; a++)
			 for (int b = 0; b <= 1111; b++)
			 {
				 int c = a + b;
				 if (fun(a) + fun(b) + fun(c) == m-4)
				 {
					 System.out.println(a + " + " + b + " = " + c);
					 sum++;
				 }
			 }
		 System.out.println("一共可以拼出"+sum+"個不同的等式");
		 sc.close();
	}
}

 

數的全排列

問題描述

輸入一個自然數N(1<=N<=9),從小到大輸出用1~N組成的所有排列,也就說全排列。例如輸入3則輸出
123
132
213
231
312
321

輸入格式:

輸入一個自然數N(1<=N<=9)

輸出格式:

N的全排列,每行一個

限制:

每個測試點1秒

樣例 1 :

輸入:
2
輸出:
12
21

樣例 2 :

輸入:
3
輸出:
123
132
213
231
312
321
package com.qianwei.chapter3;

import java.util.Scanner;

public class FullPermutation {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a = new int[n];
		for (int i=1;i<=n;i++)
			a[i-1] = i;
		f(a,0);
		sc.close();
	}
	
	private static void f(int[] x, int k) {
		if(k>=x.length){
			for (int i=0;i<x.length;i++)
				System.out.print(x[i]+" ");
			System.out.println();
			return;
		}
		
		for(int i=k; i<x.length; i++){
			{int t=x[k]; x[k]=x[i]; x[i]=t;}
			f(x,k+1);
			{int t=x[k]; x[k]=x[i]; x[i]=t;}  
		}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章