2025年5月2日 星期五

UVa _ 10004 _ Bicoloring

 def is_bicolorable(adj_list, n):

    for start_node in range(n):

        color = [-1] * n        

        if color[start_node] != -1:

            continue

        # Iterative approach prevents stack overflow for large graphs

        stack = [(start_node, 0)] 

        color[start_node] = 0

        while stack:

            node, node_color = stack.pop()

            next_color = 1 - node_color  # Toggle between 0 and 1

            for neighbor in adj_list[node]:

                if color[neighbor] == -1:

                    color[neighbor] = next_color

                    stack.append((neighbor, next_color))

                elif color[neighbor] == node_color:  # Same color conflict

                    return False

    return True

while True:

    n = int(input())

    if n == 0:

        break

    m = int(input())

    adj_list = [[] for _ in range(n)] # Build adjacency list 

    for _ in range(m):

        a, b = map(int, input().split())

        adj_list[a].append(b)

        adj_list[b].append(a)

    print("BICOLORABLE." if is_bicolorable(adj_list, n) else "NOT BICOLORABLE.")

2025年4月12日 星期六

UVa _ 00532 _ Dungeon Master

 #include <iostream>

#include <queue>

#include <cstdio>

#include <cstring>

using namespace std;

const int MAXN = 32;

char dungeon[MAXN][MAXN][MAXN];

int Distance[MAXN][MAXN][MAXN];

int L, R, C;

const int direction[6][3] = {{-1, 0, 0}, {1, 0, 0}, {0, -1, 0},

                                     {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};

struct point_type { int x; int y; int z; };

int BFS(int start_i, int start_j, int start_k) {

    // keypoint: Init Distance (-1 = not visited)

    for (int i = 0; i < L; ++i)

        for (int j = 0; j < R; ++j)

            for (int k = 0; k < C; ++k)

                Distance[i][j][k] = -1;

    // keypoint: BFS queue

    queue<point_type> q;

    q.push({start_i, start_j, start_k});

    Distance[start_i][start_j][start_k] = 0;

    while (!q.empty()) {

        point_type cur = q.front();

        q.pop();

        // keypoint: Found end

        if (dungeon[cur.x][cur.y][cur.z] == 'E')

            return Distance[cur.x][cur.y][cur.z];

        for (int i = 0; i < 6; ++i) {

            point_type nxt = {cur.x + direction[i][0], cur.y + direction[i][1], cur.z + direction[i][2]};

            // keypoint: Boundary check

            if (nxt.x < 0 || nxt.x >= L || nxt.y < 0 || nxt.y >= R || nxt.z < 0 || nxt.z >= C) continue;

            // keypoint: Wall check

            if (dungeon[nxt.x][nxt.y][nxt.z] == '#') continue;

            // keypoint: Visited check

            if (Distance[nxt.x][nxt.y][nxt.z] != -1) continue;

            Distance[nxt.x][nxt.y][nxt.z] = Distance[cur.x][cur.y][cur.z] + 1;

            q.push(nxt);

        }

    }

    return -1; // keypoint: No path

}

int main() {

    while (scanf("%d%d%d", &L, &R, &C) == 3) {

        if (!L && !R && !C) break;

        int start_i, start_j, start_k;

        for (int i = 0; i < L; ++i)

            for (int j = 0; j < R; ++j) {

                scanf("%s", dungeon[i][j]);

                for (int k = 0; k < C; ++k)

                    if (dungeon[i][j][k] == 'S')

                        start_i = i, start_j = j, start_k = k;

            }

        int minute = BFS(start_i, start_j, start_k);

        if (minute != -1)

            printf("Escaped in %d minute(s).\n", minute);

        else

            printf("Trapped!\n");

    }

    return 0;

}

2025年3月28日 星期五

UVa _11456 _ Trainsorting

 #include <iostream>

#include <vector>

using namespace std;

int findLongestSymmetricSubsequence(int sequenceLength) {

    // Create mirrored train sequence

    vector<int> symmetricSequence(sequenceLength * 2);

    // Track length of increasing subsequence for each position

    vector<int> subsequenceLengths(sequenceLength * 2, 1);

    int maxSubsequenceLength = 0;

    // Read and mirror the sequence

    for (int i = 0; i < sequenceLength; ++i) {

        int trainCarValue;

        cin >> trainCarValue;

        symmetricSequence[sequenceLength + i] = symmetricSequence[sequenceLength - i - 1] = trainCarValue;

    }

    // Find longest increasing subsequence

    for (int currentIndex = 0; currentIndex < sequenceLength * 2; ++currentIndex) {

        for (int prevIndex = 0; prevIndex < currentIndex; ++prevIndex) {

            // If current element is larger than previous, update subsequence length

            if (symmetricSequence[currentIndex] > symmetricSequence[prevIndex]) {

                subsequenceLengths[currentIndex] = max(

                    subsequenceLengths[currentIndex], 

                    subsequenceLengths[prevIndex] + 1

                );

            }

            // Track maximum subsequence length

            maxSubsequenceLength = max(maxSubsequenceLength, subsequenceLengths[currentIndex]);

        }

    }


    return maxSubsequenceLength;

}


int main() {

    // Optimize input/output performance

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

    cout.tie(nullptr);


    int numberOfTestCases;

    cin >> numberOfTestCases;


    // Process each test case

    while (numberOfTestCases--) {

        int trainLength;

        cin >> trainLength;


        // Solve and output result for current test case

        cout << findLongestSymmetricSubsequence(trainLength) << "\n";

    }


    return 0;

}

2025年3月27日 星期四

UVa _ 10336 _ Rank the Languages

 import sys

# Constants

MX = 10000

class Type:

    def __init__(self, id=None, value=0):

        self.id = id

        self.value = value

def comp(a):

    # Comparison function for sorting ranks

    # Primary sort: descending order of value (using negative to achieve descending)

    # Secondary sort: ascending order of id (in case of equal values)

    # Useful for ranking components by size and then by identifier

    return (-a.value, a.id)

def init(h, w):

    # Initialize a list of Type objects with default values

    # Creates an empty data structure of specified dimensions

    # Useful for pre-allocating space for graph-related data structures

    return [Type() for _ in range(h * w)]

def set_rank(ranks, c, r):

    for rank in ranks:

        if rank.id == c:

            rank.value += r

            return    

    new_rank = Type(id=c, value=r)

    ranks.append(new_rank)

def dfs_visit(graph, a, b, h, w):

    # Capturing the original color/type of the current cell before modification

    temp_c = graph[a][b]

    # label v as discovered

    # Mark the current cell as 'visited' to prevent re-exploration and avoid infinite recursion

    graph[a][b] = 'G'

    

    # Directional movements represent the possible traversal directions

    # These coordinates allow checking adjacent cells (left, up, right, down)

    dr = [0, -1, 0, 1]

    dc = [-1, 0, 1, 0]

    # for all directed edges from v to w that are in G.adjacentEdges(v) do

    # Iterate through all four possible adjacent directions

    for i in range(4):

        r = dr[i] + a

        c = dc[i] + b

        # if vertex w is not labeled as discovered then

        # Check if the adjacent cell is within graph boundaries and of the same color/type

        if (0 <= r < h and 0 <= c < w and 

            graph[r][c] == temp_c):

            # recursively call DFS(G, w)

            # Explore the connected component by recursively visiting adjacent cells

            dfs_visit(graph, r, c, h, w)

    # Mark the cell as completely explored to distinguish from undiscovered cells

    graph[a][b] = 'B'


def dfs(graph, h, w):

    # Initialize a list to store ranked components

    ranks = []

    # for all directed edges from v to w that are in G.adjacentEdges(v) do

    # Traverse through entire graph to find and explore connected components

    for i in range(h):

        for j in range(w): 

            # if vertex w is not labeled as discovered then

            # Check if the current cell hasn't been explored in previous DFS calls

            if graph[i][j] not in ['G', 'B']: 

                # Assign initial rank to the newly discovered component

                set_rank(ranks, graph[i][j], 1)  

                # recursively call DFS(G, w)

                # Start DFS from this undiscovered cell to explore its entire component

                dfs_visit(graph, i, j, h, w)

    return ranks


def process_world(h, w, graph_input):

    # Convert input to 2D list for easier manipulation

    graph = [list(row) for row in graph_input]

    # Perform depth-first search to identify and rank components

    ranks = dfs(graph, h, w)

    # Sort ranks in descending order of component size, with secondary sorting by component ID

    ranks.sort(key=comp)

    return ranks


test_cases = int(input())

cases = 0


for _ in range(test_cases):

    h, w = map(int, input().split())

    graph_input = [input() for _ in range(h)]

    cases += 1

    ranks = process_world(h, w, graph_input)

    print(f"World #{cases}")

    for rank in ranks:

        print(f"{rank.id}: {rank.value}")

2025年2月14日 星期五

SMASHIN' SCOPE

 SMASHIN’ SCOPE is an acronym, created by Tony Buzan, to assist with memorization:

  • Synesthesia/Sensuality 
  • Movement
  • Association
  • Sexuality
  • Humor
  • Imagination
  • Numbers
  • Symbolism
  • Color
  • Order and/or Sequence
  • Positive Images
  • Exaggeration

2022年3月15日 星期二

thread APIs for C/C++ : Creation & Synchronization

Threads share one address space (that is, they can all examine and modify the same variables). On the other hand, each thread has its own registers and execution stack pointer(執行堆疊), and perhaps private memory.

#include <iostream>

#include <condition_variable> // condition variable 條件變量

#include <thread>

#include <chrono>

 

std::condition_variable cv;

std::mutex cv_m;  // This mutex is used for three purposes:

                              // 1) to synchronize accesses to i

                              // 2) to synchronize accesses to std::cerr

                              // 3) for the condition variable cv

int i = 0;

void waits() //used by t1,t2 & t3

{

    std::unique_lock<std::mutex> lk(cv_m);

    std::cerr << "Waiting... \n";

    cv.wait(lk, []{return i == 1;}); //wait(lock)

    std::cerr << "...finished waiting. i == 1\n";

}

void signals()// used by thread t4

{

    std::this_thread::sleep_for(std::chrono::seconds(5));

    {

        std::lock_guard<std::mutex> lk(cv_m);

        std::cerr << "Notifying...\n";

    }

    cv.notify_all();

 

    std::this_thread::sleep_for(std::chrono::seconds(5));

    {

        std::lock_guard<std::mutex> lk(cv_m);

        i = 1;

        std::cerr << "Notifying again...\n";

    }

    cv.notify_all();

}

 

int main()

{

    std::thread t1(waits), t2(waits), t3(waits), t4(signals);

    t1.join(); 

    t2.join(); 

    t3.join();

    t4.join();

}

/*

Produce results in sequence: 

1.thread t1,t2,t3 are waiting

Waiting...

Waiting...

Waiting...

2. broadcast after 5 s

Notifying...

3. broadcast after another 5 s

Notifying again...

4. thread t1,t2,t3 are unlocked

...finished waiting. i == 1

...finished waiting. i == 1

...finished waiting. i == 1

*/



2021年9月22日 星期三

My second Java Program - multithreading - SLOC=56

package waitNotify;

class Badminton { // 在羽球類別中,設定羽毛球物件的屬性和方法

   private boolean isShooting = false;

   public synchronized void sShuttlecock(int tNo) {

   while (isShooting) {

   try {

   wait();

   } catch (InterruptedException e) {}

   }

   System.out.println("射出第"+tNo+" 顆羽球");

   isShooting = true;

   notify();

   }

   public synchronized void hShuttlecock(int aNo) {

   while (!isShooting) {

   try {

   wait();

   } catch (InterruptedException e) {}

   }

   System.out.println("擊回第"+aNo+" 顆羽球");

   isShooting = false;

   notify();

   }

}

class Shooting implements Runnable{

Badminton shuttlecock;

Shooting (Badminton shuttlecock){

this.shuttlecock = shuttlecock;

}

public void run() {

for (int i = 1; i <= 5; i++) {

shuttlecock.sShuttlecock(i);

}

}

}

class Hit implements Runnable{

Badminton shuttlecock;

Hit (Badminton shuttlecock){

this.shuttlecock = shuttlecock;

}

public void run() {

for (int i = 1; i <= 5; i++) {

shuttlecock.hShuttlecock(i);

}

}

}

public class WaitNotify {

public static void main(String[] args) {

// TODO Auto-generated method stub

Badminton shuttlecock = new Badminton(); 

Thread machine = new Thread(new Shooting(shuttlecock));

Thread hitter = new Thread(new Hit(shuttlecock));

machine.start();

hitter.start();

}

}