1. 程式人生 > >POJ 3126 & 2251 & 1321 & 3278 (DFS | BFS)

POJ 3126 & 2251 & 1321 & 3278 (DFS | BFS)

POJ 3126 & 2251 & 1321 & 3278 (DFS | BFS)


POJ - 3126 - Prime Path

題目連結

題目大意

第一個數T代表測試樣例個數,下面每一行是一個測試樣例,每行輸入兩個數ab,這兩個數都是1000~9999之間的素數,現在要求你從第一個數變成第二個數,每次變換可以(只可以)改變其中的一個數字,而且改變之後的那個數必須是素數

,問能否經過有限次的這樣變化,將第一個素數a變成第二個素數b,要你求最少的變化步數。

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0

解析

相當於求無權圖的最短路徑(有權圖用dijkstra),用BFS即可。

  • 篩素數可以使用埃拉託斯特尼篩法,這個在bfs判斷下一個節點進入佇列時使用;
  • 然後主要就是每次變化四個數,每個數從0~9之間變化,得到下一個節點,然後判斷是否滿足條件,如果滿足條件進佇列即可。
import java.io.BufferedInputStream;
import
java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { private static class Clazz{ public int num; public int step; public Clazz(int num, int step) { this.num = num; this.step = step;
} } public static final int MAX = 10000; private static boolean[] sieve(){ boolean[] is_prime = new boolean[MAX]; Arrays.fill(is_prime, true); is_prime[0] = is_prime[1] = false; for(int i = 2; i < MAX; i++){ if(is_prime[i]){ for(int j = i*i; j < MAX; j += i) is_prime[j] = false; } } return is_prime; } public static int[] separate(int num){ int[] arr = new int[4]; int i = 0; while(num > 0){ arr[i++] = num % 10; num /= 10; } return arr; } public static int revert(int[] sep){ int res = 0; for(int i = 0; i < sep.length; i++) res += sep[i] * (int)Math.pow(10, i); return res; } public static int bfs(int s, int e, boolean[] is_prime, boolean[] vis){ Queue<Clazz> queue = new LinkedList<Clazz>(); queue.add(new Clazz(s, 0)); vis[s] = true; // 和dijkstra不同, bfs一開始標記為true int[] aArr, bArr; // 兩個陣列 while(!queue.isEmpty()){ Clazz cur = queue.poll(); if(e == cur.num){ return cur.step; } aArr = separate(cur.num); for(int i = 0; i < 4; i++) { bArr = Arrays.copyOf(aArr, aArr.length); for(int j = 0; j < 10; j++){ bArr[i] = j; int nxtNum = revert(bArr); if(nxtNum > 1000 && nxtNum < 10000 && nxtNum != cur.num && !vis[nxtNum] && is_prime[nxtNum]){ vis[nxtNum] = true; queue.add(new Clazz(nxtNum, cur.step + 1)); } } } } return -1; } public static void main(String[] args){ Scanner cin = new Scanner(new BufferedInputStream(System.in)); int T = cin.nextInt(); while(T-- > 0){ int s = cin.nextInt(); int e = cin.nextInt(); boolean[] is_prime = sieve(); // 篩選 0~10000的素數 boolean[] vis = new boolean[MAX]; int res = bfs(s, e, is_prime, vis); System.out.println(res == -1 ? "Impossible" : res); } } }

POJ - 2251 - Dungeon Master

題目連結

題目大意

給你一個三維的立方體牢籠,#是不能走的,.是可以走的,S是起點,E是終點,如果可以走(不是#),你可以走上、下(上下相當於換樓層)、東、西、南、北 6 個方向,問你能否從SE,如果可以,輸出步數,否則輸出Impossible

Sample Input

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!

解析

三維的簡單bfs

import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    private static class State{
        public int le;
        public int x;
        public int y;
        public int step;

        public State(int le, int x, int y, int step) {
            this.le = le;
            this.x = x;
            this.y = y;
            this.step = step;
        }
    }

    public static int level, row, col;
    public static String[][] str;
    public static boolean success;
    public static int[][] dir = { {0,-1,0}, {0, 0, 1}, {0, 1, 0}, {0, 0, -1}, {-1, 0, 0}, {1, 0, 0}};

    public static boolean checkBoundary(int a, int b, int c){
        return a >= 0 && a < level && b >= 0 && b < row && c >= 0 && c < col;
    }

    public static void bfs(State start, State end){
        Queue<State>queue = new LinkedList<State>();
        boolean[][][] vis = new boolean[level][row][col];
        vis[start.le][start.x][start.y] = true;
        queue.add(start);
        while(!queue.isEmpty()){
            State cur = queue.poll();
            if(cur.le == end.le && cur.x == end.x && cur.y == end.y){
                System.out.println("Escaped in " + cur.step + " minute(s).");
                success = true;
                break;
            }
            for(int i = 0; i < 6; i++){
                int nle = cur.le + dir[i][0];
                int nx = cur.x + dir[i][1];
                int ny = cur.y + dir[i][2];
                if(checkBoundary(nle, nx, ny) && str[nle][nx].charAt(ny) != '#' && !vis[nle][nx][ny] ){
                    vis[nle][nx][ny] = true;
                    queue.add(new State(nle, nx, ny , cur.step+1));
                }
            }
        }
    }

    public static void main(String[] args) {

        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        while (cin.hasNext()) {
            level = cin.nextInt();
            row = cin.nextInt();
            col = cin.nextInt();
            if(level == 0 && row == 0 && col == 0)
                break;

            str = new String[level][row];
            for (int i = 0; i < level; i++) {
                for (int j = 0; j < row; j++) {
                    str[i][j] = cin.next();
                }
            }

            State start, end = null;
            // find the end position
            boolean flag = false;
            for (int i = 0; i < level; i++) {
                for (int j = 0; j < row; j++) {
                    for (int k = 0; k < col; k++) {
                        if (str[i][j].charAt(k) == 'E') {
                            end = new State(i, j, k, 0);
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                        break;
                }
                if (flag)
                    break;
            }
            success = false;
            for (int i = 0; i < level; i++) {
                for (int j = 0; j < row; j++) {
                    for (int k = 0; k < col; k++) {
                        if (str[i][j].charAt(k) == 'S') {
                            start = new State(i, j, k, 0);
                            bfs(start, end);
                        }
                    }
                }
            }
            if (!success)
                System.out.println("Trapped!");
        }
    }
}


POJ - 1321 - 棋盤問題

題目連結

題目大意

給你一個棋盤,但是棋盤上只有#的可以擺放棋子(.不行),且要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,擺放k個棋子的所有可行的擺放方案C

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1

解析

這個題目看上去和n皇后問題有點類似,但是要注意它們之間的不同:

  • n皇后問題是必須每一行都要擺上皇后,這個題目是隻需要擺放k個棋子就可以;
  • 所以在遞迴的時候,不能擺放好了curRow(當前行以及之前行)之後去遞迴下一行,而是要去遞迴[curRow~n)所有行都可以嘗試擺放,只要擺放k個就可以了,所以情況會多很多。
  • 然後記錄某一列是否擺放和n皇后一樣,使用一個boolean陣列即可,同樣記得遞迴之後c[j] = false還原;
import java.io.*;
import java.util.Scanner;

public class Main {

    private static int sum;

    public static void dfs(String[] str, boolean[] c, int curRow, int k, int n) {
        if (k == 0) {
            sum++;
            return;
        }
        // curRow前面的已經放好了,後面[curRow~n]之間的我都要試一下(注意不是皇后問題:只要試curRow+1的)
        for (int i = curRow; i < n; i++) {
            for (int j = 0; j < n; j++) {    //嘗試放在每一列
                if (!c[j] && str[i].charAt(j) == '#') {
                    c[j] = true;            // 將curRow棋子放到j列
                    dfs(str, c, i + 1, k - 1, n);
                    c[j] = false;
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        while (cin.hasNext()) {
            int n = cin.nextInt();
            int k = cin.nextInt();  // k個棋子
            if (n == -1 && k == -1)
                break;
            String[] str = new String[n];
            for (int i = 0; i < n; i++)
                str[i] = cin.next();
            sum = 0;
            dfs(str, new boolean[n], 0, k, n);
            System.out.println(sum)
            
           

相關推薦

POJ 3126 &amp; 2251 &amp; 1321 &amp; 3278 (DFS | BFS)

POJ 3126 & 2251 & 1321 & 3278 (DFS | BFS) POJ - 3126 - Prime Path POJ - 2251 - Dungeon Master POJ - 1321 - 棋盤問題 POJ -

POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

cin 列數 tle 圖片 逆時針 sta div ima ostream POJ 3083 -- Children of the Candy Corn(DFS+BFS) 題意: 給定一個迷宮,S是起點,E是終點,#是墻不可走,.可以走 1)先輸出左轉優先時,從S到E的步數

POJ 3450--Corporate Identity【KMP &amp;amp;&amp;amp; 枚舉】

pan else common ant sid comm letter recently there Corporate Identity Time Limit: 3000MS Memory Limit: 65536K T

POJ 3177--Redundant Paths【無向圖添加最少的邊成為邊雙連通圖 &amp;amp;&amp;amp; tarjan求ebc &amp;amp;&amp;amp; 縮點構造縮點樹】

when tab sub exp 無向圖 redundant -m term 一個點 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submis

poj 2931 Building a Space Station &amp;lt;克魯斯卡爾&amp;gt;

accep for each ppi ons cee ont line 求解 0.11 Building a Space Station Time Limit: 1000MS Memory Limit: 30000K

POJ 3252 Round Numbers(數位dp&amp;amp;記憶化搜索)

for tor ddc name nes rep ref round end 題目鏈接:[kuangbin帶你飛]專題十五 數位DP E - Round Numbers 題意 給定區間。求轉化為二進制後當中0比1多或相等的數字的個數。 思路

POJ 3691 DNA repair ( Trie圖 &amp;&amp; DP )

queue src can bsp next mem %d mil ++ 題意 : 給出 n 個病毒串,最後再給出一個主串,問你最少改變主串中的多少個單詞才能使得主串中不包含任何一個病毒串 分析 : 做多了AC自動機的題,就會發現這些題有些都是很套路的題目。在構建 Tr

POJ 1011 Sticks(搜索 &amp;&amp; 剪枝 &amp;&amp; 經典)

closed play turn 深搜 span rem += 成功 curl 題意 : 有n根木棍(n<=64),它們由一些相同長度的木棍切割而來,給定這n根木棍的長度,求使得原來長度可能的最小值。 分析 : 很經典的深搜題目,我們發現答案只可能是所有木棍長度總

POJ 3280 Cheapest Palindrome ( 區間DP &amp;&amp; 經典模型 )

ide aps class nbsp 圖片 pri 子串 microsoft using 題意 : 給出一個由 n 中字母組成的長度為 m 的串,給出 n 種字母添加和刪除花費的代價,求讓給出的串變成回文串的代價。 分析 : 原始模型 ==> 題意和本題差不多,

POJ-1284 Primitive Roots---原根&amp;歐拉函數

urn ace info als while long space msu sin 題目鏈接: https://cn.vjudge.net/problem/POJ-1284 題目大意: 就是給出一個奇素數,求出他的原根的個數。 解題思路: 由於是m是奇素數,m的歐拉函數

BZOJ 2288: 【POJ Challenge】生日禮物 堆&amp;&amp;鏈表

names queue 技術分享 name 個數 tchar c代碼 turn 備份 就是堆+鏈表,十分像 數據備份 對吧? 把相鄰的正數和相鄰的負數合並成一整個正數塊和負數塊,最後只剩一些交替相間的正塊與負塊了吧? 顯然,正塊的個數<=m時,全部選走就獲得了最大

解決QT:forward declaration of &amp;#39;struct Ui::xxx&amp;#39;;invalid use of incomplete struct &amp;quot;Ui::Widget&amp;quot; 等莫名奇異錯誤

執行 center dex text nco jsb ims complete class 今天在進行QT Widget的UI設計時,改了下Widget的對象名,然後在多次成功編譯執行後,執行清理,又一次構建,就出現了好多莫名奇異的錯誤: widget.

IOS開發——手勢 &amp;amp; 傳感器 &amp;amp; 物理引擎

github上 content 物理 alt img .net amp 技術分享 lan 這次思維導圖比較雜,demo已經所有上傳到github上,小編的github地址是:狂戳 先看下效果圖: 手勢畫板: 物理引擎: 傳感器: IOS開發——手

小胖說事31------iOS 真機編譯錯誤&amp;quot;“XXX”的 iPod&amp;quot; and run &amp;quot;XXX&amp;quot; again, or if &amp;quot;XXX&amp;quot; is still running

是不是 col ont lec bug div attach tracking 進程關閉 在真機上測試時用一會就出現例如以下信息,且應用掛掉。 Restore the connection to "“XXX”的 iPod" and run "XXX" again, o

『TensorFlow』隊列&amp;多線程&amp;TFRecod文件_我輩當高歌

gradient 函數 http who epo variable nbsp 其他 新建 TF數據讀取隊列機制詳解 TFR文件多線程隊列讀寫操作: TFRecod文件寫入操作: import tensorflow as tf def _in

atitit.js&amp;#160;與c#&amp;#160;java交互html5化的原理與總結.doc

pad 托管 works onclick rgb sar com 2.0 swing atitit.js 與c# java交互html5化的原理與總結.doc 1. 實現html5化界面的要解決的策略 1 1.1. Js交互 1 1.2. 動態參數個

使用 gradle 在編譯時動態設置 Android resValue / BuildConfig / Manifes中&amp;lt;meta-data&amp;gt;變量的值

-m lean view data- ret post 不能 flavor ... 轉載請標明出處:http://blog.csdn.net/xx326664162/article/details/49247815 文章出自:薛瑄的博客 你也能夠

【C#】報表制作&amp;lt;機房重構&amp;gt;

接下來 機房 工具 學習 test trac fcm 報表 感覺 前言 和VB須要引用其它報表軟件不同,VS自帶報表設計的功能,初次嘗試。就感受到了它的強大之處。 報表制作 話不多說。直接報表的制作過程。 1、首先,我們要先制作一個報表的

[Hibernate]Access to DialectResolutionInfo cannot be null when &amp;#39;hibernate.dialect&amp;#39; not set

util create size dialect eat private 解決 代碼 ror 使用Hibernate官方文檔上的下面代碼進行測試時報出這個異常。 org.hibernate.HibernateException: Access to Dialect

PoEdu - Windows階段班 【Po學校】Lesson006_線程_線程的啟動到消亡 &amp;線程狀態 &amp; 線程安全 &amp; CONTEXT結構體 &amp; 令牌鎖

turn within 周期 銷毀 hose pen inf obj objects 011_線程啟動到死亡的詳細講解 1. 線程內核對象 使用計數 2 ##決定當前線程何時銷毀 暫停計數 1 ##UINT類型初始為1,可以暫停多次,如置為0則取消暫停。 退出代碼