D - String Successor

D - String Successor
Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

The successor to a string can be calculated by applying the following rules:

  • Ignore the nonalphanumerics unless there are no alphanumerics, in this case, increase the rightmost character in the string.
  • The increment starts from the rightmost alphanumeric.
  • Increase a digit always results in another digit ('0' -> '1', '1' -> '2' ... '9' -> '0').
  • Increase a upper case always results in another upper case ('A' -> 'B', 'B' -> 'C' ... 'Z' -> 'A').
  • Increase a lower case always results in another lower case ('a' -> 'b', 'b' -> 'c' ... 'z' -> 'a').
  • If the increment generates a carry, the alphanumeric to the left of it is increased.
  • Add an additional alphanumeric to the left of the leftmost alphanumeric if necessary, the added alphanumeric is always of the same type with the leftmost alphanumeric ('1' for digit, 'A' for upper case and 'a' for lower case).

Input

There are multiple test cases. The first line of input is an integer T ≈ 10000 indicating the number of test cases.

Each test case contains a nonempty string s and an integer 1 ≤ n ≤ 100. The string s consists of no more than 100 characters whose ASCII values range from 33('!') to 122('z').

Output

For each test case, output the next n successors to the given string s in separate lines. Output a blank line after each test case.

Sample Input

4
:-( 1
cirno=8 2
X 3
/**********/ 4

Sample Output

:-)

cirno=9
cirnp=0

Y
Z
AA

/**********0
/**********1
/**********2
/**********3

 这道题目的大致意思是:

1.如果没有字母或是数字那么就忽视它,增加最右边字符串中的字符;

2.else 增加从最右边的字母或是数字开始;

3.如果生成了一个进位(即为9->0; z->a; Z->A)这样叫做进位,那么该字母数字的左边的那个字母数字就增加1;

4.是最重要的一步,如果该字母数字的左边没有其他东西,那么就在最左边插进去一个相对应形式的字母数字;('1' for digit, 'A' for upper case and 'a' for lower case).

(其实也就相当于长度只有1的情况);

 

参考一个大神写下如下代码,

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<ctype.h>
using namespace std;
string a;
int flag=0,len=0;
int ju(char c){
	//判断其中是否还有字符或数字 
	if(islower(c)||isupper(c)||('0'<=c&&c<='9')){
			return 1;
	}
	return 0;
}
void change(string& a,int i){
	char c;
	if(a[i]=='z'||a[i]=='Z'||a[i]=='9'){
		if(a[i]=='z')  {a[i]='a';  c='a';} 
		else if(a[i]=='Z') {a[i]='A';  c='A';}
		else if(a[i]=='9') {a[i]='0'; c='1';}	//注意这里的c要改成c='1'; 
	}
	else{
		a[i]++; 
		return;
	}
	int j;
	for(j=i-1;j>=0;j--)
	if(ju(a[j]))  break;
	string::iterator it=a.begin();
	if(j>=0)  change(a,j);
	//insert: 在i前面的那个位置前面插入一个字符串c; 
	else if(j<0)  a.insert(i+it,c);
}
int main(){
	int T,i,j,n,t;
	cin>>T;
	while(T--){
		cin>>a>>n;
		for(i=1;i<=n;i++){
			//注意每次都要求一次它的长度; 
			len=a.size();
			flag=0;
			for(j=len-1;j>=0;j--){
				if(ju(a[j])){
					flag=1; break;
				}
			}
			if(!flag){
				a[len-1]++;
				cout<<a<<endl;
				continue;
			}
			change(a,j);
			cout<<a<<endl;
		}
		cout<<endl;
	}
}

*注意这里用c++函数的string比较方便;因为它可以随时在前端插入
ju函数是用来判断该字符串中是否还有字符或是字符数字; 如果有的话,那么就在main函数中保存那个位置;

change函数的目的是:

1.判断是否要进位,如果要进位的话,那么把要进位的字符数字保存一个在c中,以便之后插入字符串a中的最前端;

2.如果不用进位的话,那么就进行自增就好;此时要注意return直接返回,那么就不会进行下面的语句了;

3.如果1条件成立的话,那么就for一遍,判断在i之前是否还有字符或是字符数字,如果有的话,那么j肯定是大于等于0的,然后再次进行change函数的调用 ; 如果没有,那么就把c字符插入到i的前一位中去;

4.如果全是其他乱七八糟的字符的话,那么就直接在最后一位加1,这里十分巧妙,当n十分大的时候,会产生字符或是数字,此时flag就会判断为1,然后就会自动的进行到change的函数中去了;

 

思路十分巧妙,多看看就能更好的去理解,加油吧。终有一天你能成为girl的骄傲@all girls!

# influxd --help WARN[0000]log.go:228 gosnowflake.(*defaultLogger).Warn DBUS_SESSION_BUS_ADDRESS envvar looks to be not set, this can lead to runaway dbus-daemon processes. To avoid this, set envvar DBUS_SESSION_BUS_ADDRESS=$XDG_RUNTIME_DIR/bus (if it exists) or DBUS_SESSION_BUS_ADDRESS=/dev/null. Start up the daemon configured with flags/env vars/config file. The order of precedence for config options are as follows (1 highest, 3 lowest): 1. flags 2. env vars 3. config file A config file can be provided via the INFLUXD_CONFIG_PATH env var. If a file is not provided via an env var, influxd will look in the current directory for a config.{json|toml|yaml|yml} file. If one does not exist, then it will continue unchanged. Usage: influxd [flags] influxd [command] Available Commands: downgrade Downgrade metadata schema used by influxd to match the expectations of an older release help Help about any command inspect Commands for inspecting on-disk database data recovery Commands used to recover / regenerate operator access to the DB run Start the influxd server upgrade Upgrade a 1.x version of InfluxDB version Print the influxd server version Flags: --assets-path string override default assets by serving from a specific directory (developer mode) --bolt-path string path to boltdb database (default "/root/.influxdbv2/influxd.bolt") --e2e-testing add /debug/flush endpoint to clear stores; used for end-to-end tests --engine-path string path to persistent engine files (default "/root/.influxdbv2/engine") --feature-flags stringToString feature flag overrides (default []) --flux-log-enabled enables detailed logging for flux queries --hardening-enabled enable hardening options (disallow private IPs within flux and templates HTTP requests; disable file URLs in templates) -h, --help help for influxd --http-bind-address string bind address for the REST HTTP API (default ":8086") --http-idle-timeout duration max duration the server should keep established connections alive while waiting for new requests. Set to 0 for no timeout (default 3m0s) --http-read-header-timeout duration max duration the server should spend trying to read HTTP headers for new requests. Set to 0 for no timeout (default 10s) --http-read-timeout duration max duration the server should spend trying to read the entirety of new requests. Set to 0 for no timeout --http-write-timeout duration max duration the server should spend on processing+responding to requests. Set to 0 for no timeout --influxql-max-select-buckets int The maximum number of group by time bucket a SELECT can create. A value of zero will max the maximum number of buckets unlimited. --influxql-max-select-point int The maximum number of points a SELECT can process. A value of 0 will make the maximum point count unlimited. This will only be checked every second so queries will not be aborted immediately when hitting the limit. --influxql-max-select-series int The maximum number of series a SELECT can run. A value of 0 will make the maximum series count unlimited. --instance-id string add an instance id for replications to prevent collisions and allow querying by edge node --log-level Log-Level supported log levels are debug, info, and error (default info) --metrics-disabled Don't expose metrics over HTTP at /metrics --no-tasks disables the task scheduler --overwrite-pid-file overwrite PID file if it already exists instead of exiting --pid-file string write process ID to a file --pprof-disabled Don't expose debugging information over HTTP at /debug/pprof --query-concurrency int32 the number of queries that are allowed to execute concurrently. Set to 0 to allow an unlimited number of concurrent queries (default 1024) --query-initial-memory-bytes int the initial number of bytes allocated for a query when it is started. If this is unset, then query-memory-bytes will be used --query-max-memory-bytes int the maximum amount of memory used for queries. Can only be set when query-concurrency is limited. If this is unset, then this number is query-concurrency * query-memory-bytes --query-memory-bytes int maximum number of bytes a query is allowed to use at any given time. This must be greater or equal to query-initial-memory-bytes --query-queue-size int32 the number of queries that are allowed to be awaiting execution before new queries are rejected. Must be > 0 if query-concurrency is not unlimited (default 1024) --reporting-disabled disable sending telemetry data to https://telemetry.influxdata.com every 8 hours --secret-store string data store for secrets (bolt or vault) (default "bolt") --session-length int ttl in minutes for newly created sessions (default 60) --session-renew-disabled disables automatically extending session ttl on request --sqlite-path string path to sqlite database. if not set, sqlite database will be stored in the bolt-path directory as "influxd.sqlite". --storage-cache-max-memory-size Size The maximum size a shard's cache can reach before it starts rejecting writes. (default 1.0 GiB) --storage-cache-snapshot-memory-size Size The size at which the engine will snapshot the cache and write it to a TSM file, freeing up memory. (default 25 MiB) --storage-cache-snapshot-write-cold-duration Duration The length of time at which the engine will snapshot the cache and write it to a new TSM file if the shard hasn't received writes or deletes. (default 10m0s) --storage-compact-full-write-cold-duration Duration The duration at which the engine will compact all TSM files in a shard if it hasn't received a write or delete. (default 4h0m0s) --storage-compact-throughput-burst Size The rate limit in bytes per second that we will allow TSM compactions to write to disk. (default 48 MiB) --storage-max-concurrent-compactions int The maximum number of concurrent full and level compactions that can run at one time. A value of 0 results in 50% of runtime.GOMAXPROCS(0) used at runtime. Any number greater than 0 limits compactions to that value. This setting does not apply to cache snapshotting. --storage-max-index-log-file-size Size The threshold, in bytes, when an index write-ahead log file will compact into an index file. Lower sizes will cause log files to be compacted more quickly and result in lower heap usage at the expense of write throughput. (default 1.0 MiB) --storage-no-validate-field-size Skip field-size validation on incoming writes. --storage-retention-check-interval Duration The interval of time when retention policy enforcement checks run. (default 30m0s) --storage-series-file-max-concurrent-snapshot-compactions int The maximum number of concurrent snapshot compactions that can be running at one time across all series partitions in a database. --storage-series-id-set-cache-size int The size of the internal cache used in the TSI index to store previously calculated series results. --storage-shard-precreator-advance-period Duration The default period ahead of the endtime of a shard group that its successor group is created. (default 30m0s) --storage-shard-precreator-check-interval Duration The interval of time when the check to pre-create new shards runs. (default 10m0s) --storage-tsm-use-madv-willneed Controls whether we hint to the kernel that we intend to page in mmap'd sections of TSM files. --storage-validate-keys Validates incoming writes to ensure keys only have valid unicode characters. --storage-wal-flush-on-shutdown Flushes and clears the WAL on shutdown --storage-wal-fsync-delay Duration The amount of time that a write will wait before fsyncing. A duration greater than 0 can be used to batch up multiple fsync calls. This is useful for slower disks or when WAL write contention is seen. (default 0s) --storage-wal-max-concurrent-writes int The max number of writes that will attempt to write to the WAL at a time. (default <nprocs> * 2) --storage-wal-max-write-delay storage-wal-max-concurrent-writes The max amount of time a write will wait when the WAL already has storage-wal-max-concurrent-writes active writes. Set to 0 to disable the timeout. (default 10m0s) --storage-write-timeout duration The max amount of time the engine will spend completing a write request before cancelling with a timeout. (default 10s) --store string backing store for REST resources (disk or memory) (default "disk") --strong-passwords enable password strength enforcement --template-file-urls-disabled disable template file URLs --testing-always-allow-setup ensures the /api/v2/setup endpoint always returns true to allow onboarding --tls-cert string TLS certificate for HTTPs --tls-key string TLS key for HTTPs --tls-min-version string Minimum accepted TLS version (default "1.2") --tls-strict-ciphers Restrict accept ciphers to: ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ECDHE_RSA_WITH_AES_128_GCM_SHA256, ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, ECDHE_RSA_WITH_AES_256_GCM_SHA384, ECDHE_ECDSA_WITH_CHACHA20_POLY1305, ECDHE_RSA_WITH_CHACHA20_POLY1305 --tracing-type string supported tracing types are log, jaeger --ui-disabled Disable the InfluxDB UI --vault-addr string address of the Vault server expressed as a URL and port, for example: https://127.0.0.1:8200/. --vault-cacert string path to a PEM-encoded CA certificate file on the local disk. This file is used to verify the Vault server's SSL certificate. This environment variable takes precedence over VAULT_CAPATH. --vault-capath string path to a directory of PEM-encoded CA certificate files on the local disk. These certificates are used to verify the Vault server's SSL certificate. --vault-client-cert string path to a PEM-encoded client certificate on the local disk. This file is used for TLS communication with the Vault server. --vault-client-key string path to an unencrypted, PEM-encoded private key on disk which corresponds to the matching client certificate. --vault-client-timeout duration timeout variable. The default value is 60s. --vault-max-retries int maximum number of retries when a 5xx error code is encountered. The default is 2, for three total attempts. Set this to 0 or less to disable retrying. --vault-skip-verify do not verify Vault's presented certificate before communicating with it. Setting this variable is not recommended and voids Vault's security model. --vault-tls-server-name string name to use as the SNI host when connecting via TLS. --vault-token string vault authentication token Use "influxd [command] --help" for more information about a command. 翻译并解析
11-12
#include <iostream> #include <vector> #include <queue> #include <stack> #include <unordered_set> #include <string> #include <algorithm> #include <iomanip> // -------------------------- Configuration -------------------------- // Toggle debug messages (can be switched via code or user input) bool ENABLE_DEBUG = false; // -------------------------- State Representation -------------------------- // Represents a location (state) in the building struct State { std::string room_label; // e.g., "B3.2", "Lift_1", "Lobby_2", "Charger" State* parent; // Pointer to parent state (for path reconstruction) // Constructor State(std::string label, State* p = nullptr) : room_label(label), parent(p) {} // For unordered_set (to track visited states) bool operator==(const State& other) const { return room_label == other.room_label; } }; // Hash function for State (required for unordered_set) namespace std { template <> struct hash<State> { size_t operator()(const State& s) const { return hash<string>()(s.room_label); } }; } // -------------------------- Helper Functions -------------------------- /** * @brief Validates if a room label follows the building's naming convention * @param label Input room label (e.g., "A1.1", "Lift_3", "Charger") * @return True if valid, false otherwise */ bool is_valid_room_label(const std::string& label) { // Valid patterns: // 1. Room (Reception/Office): [A-N][1-3].[1-2] (e.g., A1.1, N3.2) // 2. Lobby: "Lobby_[1-3]" (e.g., Lobby_1 for ground floor) // 3. Lift: "Lift_[1-3]" (e.g., Lift_2 for first floor) // 4. Charger: Exact match "Charger" // Check Charger if (label == "Charger") return true; // Check Lobby/Lift if (label.substr(0, 6) == "Lobby_" || label.substr(0, 5) == "Lift_") { if (label.size() != 7) return false; // e.g., Lobby_1 (7 chars) char floor = label.back(); return (floor == '1' || floor == '2' || floor == '3'); } // Check Room (A-N)(1-3).(1-2) if (label.size() != 4) return false; // e.g., A1.1 (4 chars) if (!((label[0] >= 'A' && label[0] <= 'N'))) return false; // First char: A-N if (!((label[1] >= '1' && label[1] <= '3'))) return false; // Second char: 1-3 (floor) if (label[2] != '.') return false; // Third char: dot if (!((label[3] >= '1' && label[3] <= '2'))) return false; // Fourth char: 1-2 (reception/office) return true; } /** * @brief Extracts floor number from a valid room label (1=ground, 2=first, 3=second) * @param label Valid room label * @return Floor number (1-3) or -1 if invalid */ int get_floor_from_label(const std::string& label) { if (!is_valid_room_label(label)) return -1; if (label == "Charger") return 1; // Charger is on ground floor (1) if (label.substr(0, 6) == "Lobby_" || label.substr(0, 5) == "Lift_") { return label.back() - '0'; // Extract digit (1-3) } return label[1] - '0'; // For rooms (e.g., A1.1 -> '1' -> 1) } /** * @brief Goal test: Checks if the current state is the Charger * @param current Current state to test * @return True if current state is Charger, false otherwise */ bool is_goal(const State& current) { return current.room_label == "Charger"; } /** * @brief Successor function: Generates all valid next states from a given state * @param current Current state (location) * @return Vector of valid successor states */ std::vector<State> generate_successors(const State& current) { std::vector<State> successors; std::string current_label = current.room_label; int current_floor = get_floor_from_label(current_label); if (current_floor == -1) return successors; // Invalid state, no successors // -------------------------- Case 1: Current state is a Room (e.g., A1.1, B3.2) -------------------------- if (current_label.size() == 4 && current_label[2] == '.') { char room_letter = current_label[0]; char room_type = current_label[3]; // '1'=reception, '2'=office std::string reception_label = current_label.substr(0, 3) + "1"; // e.g., B3.2 -> B3.1 (reception) std::string office_label = current_label.substr(0, 3) + "2"; // e.g., B3.1 -> B3.2 (office) // Rule: Office can only be accessed via its dedicated reception if (room_type == '2') { // Current is Office (e.g., B3.2) // Only successor is its reception (e.g., B3.1) if (is_valid_room_label(reception_label)) { successors.emplace_back(reception_label, new State(current)); } } else { // Current is Reception (e.g., B3.1) // Successor 1: Corresponding office (e.g., B3.2) if (is_valid_room_label(office_label)) { successors.emplace_back(office_label, new State(current)); } // Successor 2: Lobby of the same floor (e.g., Lobby_3 for B3.1) std::string lobby_label = "Lobby_" + std::to_string(current_floor); successors.emplace_back(lobby_label, new State(current)); } } // -------------------------- Case 2: Current state is a Lobby (e.g., Lobby_1) -------------------------- else if (current_label.substr(0, 6) == "Lobby_") { // Rule: Lobby connects to all receptions on the same floor and the Lift on the same floor std::vector<char> room_letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'K', 'L', 'M', 'N'}; std::string reception_suffix = std::to_string(current_floor) + ".1"; // e.g., 1.1 for ground floor // Add all receptions on the same floor (e.g., A1.1, B1.1, ..., N1.1 for Lobby_1) for (char letter : room_letters) { std::string reception_label = std::string(1, letter) + reception_suffix; if (is_valid_room_label(reception_label)) { successors.emplace_back(reception_label, new State(current)); } } // Add Lift on the same floor (e.g., Lift_1 for Lobby_1) std::string lift_label = "Lift_" + std::to_string(current_floor); successors.emplace_back(lift_label, new State(current)); } // -------------------------- Case 3: Current state is a Lift (e.g., Lift_2) -------------------------- else if (current_label.substr(0, 5) == "Lift_") { // Rule: Lift can move ±1 floor (if valid) and connects to Lobby on current floor // Successor 1: Lobby on the same floor std::string lobby_label = "Lobby_" + std::to_string(current_floor); successors.emplace_back(lobby_label, new State(current)); // Successor 2: Lift on floor above (if not 3rd floor) if (current_floor < 3) { std::string up_lift_label = "Lift_" + std::to_string(current_floor + 1); successors.emplace_back(up_lift_label, new State(current)); } // Successor 3: Lift on floor below (if not 1st floor) if (current_floor > 1) { std::string down_lift_label = "Lift_" + std::to_string(current_floor - 1); successors.emplace_back(down_lift_label, new State(current)); } // Successor 4: Charger (only if Lift is on ground floor (1)) if (current_floor == 1) { successors.emplace_back("Charger", new State(current)); } } // -------------------------- Case 4: Current state is Charger -------------------------- else if (current_label == "Charger") { // Charger only connects to Lift_1 (ground floor Lift) successors.emplace_back("Lift_1", new State(current)); } // Debug: Print generated successors if (ENABLE_DEBUG) { std::cout << "[DEBUG] Successors of " << current_label << ": "; for (const auto& s : successors) { std::cout << s.room_label << " "; } std::cout << std::endl; } return successors; } /** * @brief Reconstructs the path from initial state to goal state using parent pointers * @param goal Goal state (Charger) * @return Vector of state labels in path order (initial -> ... -> goal) */ std::vector<std::string> reconstruct_path(const State& goal) { std::vector<std::string> path; const State* current = &goal; // Traverse from goal to initial (parent pointers) while (current != nullptr) { path.push_back(current->room_label); current = current->parent; } // Reverse to get initial -> goal order std::reverse(path.begin(), path.end()); return path; } // -------------------------- Search Algorithms -------------------------- /** * @brief Breadth-First Search (BFS) implementation * @param initial_label Initial location label * @return Path from initial to Charger (empty if no path found) */ std::vector<std::string> bfs_search(const std::string& initial_label) { // Validate initial state if (!is_valid_room_label(initial_label)) { std::cerr << "Error: Invalid initial location '" << initial_label << "'" << std::endl; return {}; } // Initialize BFS queue and visited set std::queue<State> queue; std::unordered_set<std::string> visited; // Track visited room labels (optimization) // Enqueue initial state State initial_state(initial_label); queue.push(initial_state); visited.insert(initial_label); if (ENABLE_DEBUG) { std::cout << "[DEBUG] BFS started. Initial state: " << initial_label << std::endl; } // BFS loop while (!queue.empty()) { // Dequeue front element State current = queue.front(); queue.pop(); // Debug: Print current state being processed if (ENABLE_DEBUG) { std::cout << "[DEBUG] Processing state: " << current.room_label << std::endl; } // Goal test if (is_goal(current)) { if (ENABLE_DEBUG) { std::cout << "[DEBUG] Goal found!" << std::endl; } return reconstruct_path(current); } // Generate successors std::vector<State> successors = generate_successors(current); // Enqueue unvisited successors for (State& succ : successors) { if (visited.find(succ.room_label) == visited.end()) { visited.insert(succ.room_label); queue.push(succ); if (ENABLE_DEBUG) { std::cout << "[DEBUG] Enqueued: " << succ.room_label << std::endl; } } } } // No path found (should not happen per problem constraints) std::cerr << "Error: No path found from " << initial_label << " to Charger" << std::endl; return {}; } /** * @brief Depth-First Search (DFS) implementation (iterative, to avoid stack overflow) * @param initial_label Initial location label * @return Path from initial to Charger (empty if no path found) */ std::vector<std::string> dfs_search(const std::string& initial_label) { // Validate initial state if (!is_valid_room_label(initial_label)) { std::cerr << "Error: Invalid initial location '" << initial_label << "'" << std::endl; return {}; } // Initialize DFS stack and visited set std::stack<State> stack; std::unordered_set<std::string> visited; // Push initial state State initial_state(initial_label); stack.push(initial_state); visited.insert(initial_label); if (ENABLE_DEBUG) { std::cout << "[DEBUG] DFS started. Initial state: " << initial_label << std::endl; } // DFS loop while (!stack.empty()) { // Pop top element State current = stack.top(); stack.pop(); // Debug: Print current state being processed if (ENABLE_DEBUG) { std::cout << "[DEBUG] Processing state: " << current.room_label << std::endl; } // Goal test if (is_goal(current)) { if (ENABLE_DEBUG) { std::cout << "[DEBUG] Goal found!" << std::endl; } return reconstruct_path(current); } // Generate successors (reverse to process in same order as BFS for consistency) std::vector<State> successors = generate_successors(current); std::reverse(successors.begin(), successors.end()); // Push unvisited successors to stack for (State& succ : successors) { if (visited.find(succ.room_label) == visited.end()) { visited.insert(succ.room_label); stack.push(succ); if (ENABLE_DEBUG) { std::cout << "[DEBUG] Pushed to stack: " << succ.room_label << std::endl; } } } } // No path found (should not happen per problem constraints) std::cerr << "Error: No path found from " << initial_label << " to Charger" << std::endl; return {}; } // -------------------------- User Interface -------------------------- /** * @brief Displays main menu and gets user's search strategy choice * @return 1 for BFS, 2 for DFS, 0 for exit */ int get_search_strategy_choice() { int choice; std::cout << "\n===== HOOVI Pathfinder =====" << std::endl; std::cout << "Select search strategy:" << std::endl; std::cout << "1. Breadth-First Search (BFS) - Guarantees shortest path" << std::endl; std::cout << "2. Depth-First Search (DFS) - Alternative strategy" << std::endl; std::cout << "0. Exit" << std::endl; std::cout << "Enter your choice (0-2): "; std::cin >> choice; // Validate input while (choice < 0 || choice > 2) { std::cerr << "Invalid choice! Enter 0, 1, or 2: "; std::cin >> choice; } return choice; } /** * @brief Gets initial location from user (with validation) * @return Valid initial location label */ std::string get_initial_location() { std::string label; std::cout << "\nEnter initial location (e.g., B3.2, Lift_1, N1.1, Charger): "; std::cin >> label; // Validate label while (!is_valid_room_label(label)) { std::cerr << "Invalid location! Follow these formats:" << std::endl; std::cerr << "- Rooms: [A-N][1-3].[1-2] (e.g., A1.1, N3.2)" << std::endl; std::cerr << "- Lobby: Lobby_[1-3] (e.g., Lobby_2)" << std::endl; std::cerr << "- Lift: Lift_[1-3] (e.g., Lift_3)" << std::endl; std::cerr << "- Charger: Exact 'Charger'" << std::endl; std::cerr << "Enter again: "; std::cin >> label; } return label; } /** * @brief Toggles debug mode based on user input */ void toggle_debug_mode() { char choice; std::cout << "\nEnable debug messages? (y/n): "; std::cin >> choice; ENABLE_DEBUG = (choice == 'y' || choice == 'Y'); if (ENABLE_DEBUG) { std::cout << "Debug mode enabled. Will show search activity." << std::endl; } else { std::cout << "Debug mode disabled." << std::endl; } } /** * @brief Prints the solution path in a user-friendly format * @param path Vector of location labels (initial -> goal) * @param initial Initial location * @param strategy Search strategy used (BFS/DFS) */ void print_path(const std::vector<std::string>& path, const std::string& initial, const std::string& strategy) { if (path.empty()) { std::cerr << "No path to display." << std::endl; return; } std::cout << "\n===== Path Found Using " << strategy << " =====" << std::endl; std::cout << "Starting Location: " << initial << std::endl; std::cout << "Goal Location: Charger" << std::endl; std::cout << "Path Length: " << path.size() - 1 << " steps (total rooms: " << path.size() << ")" << std::endl; std::cout << "Path: "; for (size_t i = 0; i < path.size(); ++i) { std::cout << path[i]; if (i != path.size() - 1) { std::cout << " -> "; } } std::cout << "\n=====================================" << std::endl; } // -------------------------- Main Function -------------------------- int main() { std::cout << "Welcome to HOOVI's Pathfinding Program!" << std::endl; // Step 1: Toggle debug mode toggle_debug_mode(); // Step 2: Get search strategy int strategy_choice = get_search_strategy_choice(); if (strategy_choice == 0) { std::cout << "Exiting program. Goodbye!" << std::endl; return 0; } std::string strategy = (strategy_choice == 1) ? "BFS" : "DFS"; // Step 3: Get initial location std::string initial_location = get_initial_location(); // Step 4: Run search algorithm std::vector<std::string> path; if (strategy == "BFS") { path = bfs_search(initial_location); } else { path = dfs_search(initial_location); } // Step 5: Display results if (!path.empty()) { print_path(path, initial_location, strategy); } return 0; }
最新发布
11-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值