动态规划(01背包问题)、回溯法求解迷宫、九宫格问题


一、输入与计算

1.1 读取数据(循环读取)

1.1.1 通过getline函数可以获取一行输入数据,第三个参数表示输入的间隔符,默认为’\n’。可以将数据读入char数组,也可以读入std::string中。

#include <iostream>
#include <string>
int main()
{
		std::string data;
		std::getline(std::cin,  data);
		int count = 0;
		for (int i = data.size() - 1; i >= 0; i--)
		{
				if (data[i] == ' ') break;
				else count++;
		}
		std::cout << count << std::endl;
}
		char data[1024];
		std::cin.getline(data, 1024);

1.1.2 循环从终端读入一行一行的数据。以行为读取单位。

#include <iostream>
#include <string>
int main()
{
    std::string data;
    std::getline(std::cin, data);
    char ch;
    std::cin >> ch;
    int count = 0;
    for (int i = 0; i < data.size(); i++)
    {
        if (data[i] == std::toupper(ch) || data[i] == std::tolower(ch))
            count++;
    }
    std::cout << count << std::endl;
}

1.1.3 循环获取终端的数据,处理后输出。

#include <iostream>
#include <string>
int main()
{
    std::string data;
    while (std::getline(std::cin, data))
    {
        int count = 8 -  data.size() % 8;
        for (int i = 0; i < data.size(); i++)
        {
            if (i % 8 == 0 && i != 0)
            {
                std::cout << std::endl;
            }
            std::cout << data[i];
        }
        if (count == 8) count = 0;
        for (int i = 0; i < count; i++)
        {
            std::cout << "0";
        }
        std::cout << std::endl;
    }
}
1.2 十六进制转换为十进制
#include <iostream>
#include <string>
#include <cmath>
int main()
{
    std::string data;
    while (std::getline(std::cin, data))
    {
        unsigned int count = data.size() - 3;
        int value = 0;
        for (int i = 2; i < data.size(); i++)
        {
            char num = data[i];
            if (num >= '0' && num <= '9')
                value += std::pow(16, count) * (num - '0');
            else if (num >= 'A' && num <= 'F')
                value += std::pow(16, count) * ((num - 'A') + 10);
            else if (num >= 'a' && num <= 'f')
                value += std::pow(16, count) * ((num - 'a') + 10);
            count--;
        }
        data.clear();
        std::cout << value << std::endl;
    }
}
1.3 四舍五入并取整
#include <iostream>
#include <string>
int main()
{
		float number = 0.0f;
		std::cin >> number;
		int value = number * 10;
		std::string data = std::to_string(value);
		if (data.back() >= '5')
				std::cout << int(number + 0.5f) << std::endl;
		else 
				std::cout << int(number) << std::endl;
		return 0;
}
1.4 统计一个整数的二进制中1的个数
#include <iostream>
int main()
{
		int number = 0;
		std::cin >> number;
		int count = 0;
		while (number)
		{
				count++;
				number &= (number - 1);
		}
		std::cout << count << std::endl;
}
1.5 统计IP的类别以及掩码是否正确
#include <iostream>
#include<string>
#include <vector>

bool regular(std::string& ip)
{
		int index1 = ip.find_first_of('.');
		std::string se1 = ip.substr(0, index1);

		int index2 = ip.find_first_of('.', index1 + 1);
		std::string se2 = ip.substr(index1 + 1, index2 - index1 - 1);

		int index3 = ip.find_first_of('.', index2 + 1);
		std::string se3 = ip.substr(index2 + 1, index3 - index2 - 1);

		std::string se4 = ip.substr(index3 + 1);
		std::vector<std::string> vec = { se1, se2, se3, se4 };
		for (int i = 0; i < vec.size(); i++)
		{
				if (vec[i].empty()) return false;
				int size = 3 - vec[i].size();
				for (int j = 0; j < size; j++)
				{
						vec[i] = "0" + vec[i];
				}
		}
		ip =  vec[0] + '.' + vec[1] + '.' + vec[2] + '.' + vec[3];
		return true;
}

bool seOk(std::string& se)
{
		if (se == "255" || se == "000") return true;
		//->将十进制数转换为二进制字符串
		std::string value;
		int num = std::atoi(se.c_str());
		while (num)
		{
				if (num % 2 == 0) value = "0" + value;
				else value = "1" + value;
				num /= 2;
		}
		int index = value.find_first_of("0");
		for (int i = 0; i < index; i++)
		{
				if (value[i] == '1') return false;
		}
		return true;
}

bool isIpMask(std::string& ip)
{
		if (ip == "255.255.255.255" || ip == "000.000.000.000")
				return false;

		int index1 = ip.find_first_of('.');
		std::string se1 = ip.substr(0, index1);

		int index2 = ip.find_first_of('.', index1 + 1);
		std::string se2 = ip.substr(index1 + 1, index2 - index1 - 1);

		int index3 = ip.find_first_of('.', index2 + 1);
		std::string se3 = ip.substr(index2 + 1, index3 - index2 - 1);

		std::string se4 = ip.substr(index3 + 1);

		if (       (se1 == "255" && se2 == "255" && se3 == "255" && se4 != "255")
				|| (se1 == "255" && se2 == "255" && se3 != "255" && se4 == "000")
				|| (se1 == "255" && se2 != "255" && se3 == "000" && se4 == "000")
				|| (se1 != "255" && se2 == "000" && se3 == "000" && se4 == "000"))
		{
				bool value = true;
				value = value && seOk(se1);
				value = value && seOk(se2);
				value = value && seOk(se3);
				value = value && seOk(se4);
				return value;
		}
		return false;
}

int main()
{
		std::string data;
		int A = 0, B = 0, C = 0, D = 0, E = 0, S = 0, O = 0;
		while (std::getline(std::cin, data))
		{
				if (data.empty()) break;
				std::string ip = data.substr(0, data.find_first_of('~'));
				if (!regular(ip))
				{
						O++;
						continue;
				}
				std::string mask = data.substr(data.find_first_of('~') + 1);
				if (!regular(mask))
				{
						O++;
						continue;
				}
				if (ip.substr(0, ip.find_first_of('.')) == "000"
				|| ip.substr(0, ip.find_first_of('.')) == "127")
				{
						continue;
				}
				if (!isIpMask(mask))
				{
						O++;
						continue;
				}
				if (ip >= "001.000.000.000" && ip <= "126.255.255.255")
				{
						A++;
				}
				else if (ip >= "128.000.000.000" && ip <= "191.255.255.255")
				{
						B++;
				}
				else if (ip >= "192.000.000.000" && ip <= "223.255.255.255")
				{
						C++;
				}
				else if (ip >= "224.000.000.000" && ip <= "239.255.255.255")
				{
						D++;
				}
				else if (ip >= "240.000.000.000" && ip <= "255.255.255.255")
				{
						E++;
				}

				if (       ip >= "010.000.000.000" && ip <= "010.255.255.255"
						|| ip >= "172.016.000.000" && ip <= "172.031.255.255"
						|| ip >= "192.168.000.000" && ip <= "192.168.255.255")
				{
						S++;
				}

				data.clear();
		}
		std::cout << A << " " << B << " "  << C << " " << D << " " << E << " " << O << " " << S << std::endl;
}
1.6 数字转英文
#include <iostream>
#include <string>
#include <map>
#include <algorithm>

std::string print(std::string& value, std::map<int, std::string>& map)
{
		std::string data;
		if (value[0] != '0' && (value[1] != '0' || value[2] != '0'))
		{
				data += map[value[0] - '0'] + " hundred and ";
		}
		else if (value[0] != '0')
		{
				data += map[value[0] - '0'] + " hundred ";
		}
		if (value[1]  > '1' && value[2] == '0')
		{
				data += map[(value[1] - '0') * 10];
		}
		else if(value[1] == '1')
		{
				if(value[2] == '0')data += map[(value[1] - '0') * 10];
				else data += map[(value[1] - '0') * 10 + (value[2] - '0')];
		}
		else if (value[1] != '0' && value[2] != '0')
		{
				data += map[(value[1] - '0') * 10] + " " + map[(value[2] - '0')];
		}
		else if (value[2] != '0')
		{
				data += map[value[2] - '0'];
		}
		return data;
}

int main()
{
		std::map<int, std::string> map =
		{
				{1,"one"},{2,"two"},{3,"three"},{4,"four"},{5,"five"},{6,"six"},{7,"seven"},{8,"eight"},{9,"nine"},{10,"ten"},
				{20,"twenty"},{30,"thirty"},{40,"fouty"},{50,"fifty"},{60,"sixty"},{70,"seventy"},{80,"eighty"},{90,"ninety"},
				{11,"eleven"},{12,"twelve"},{13,"thirteen"},{14,"fourteen"},{15,"fifteen"},{16,"sixteen"},{17,"seventeen"},{18,"eighteen"},{19,"nineteen"}
		};
		std::string data;
		std::cin >> data;
		int count = 1;
		std::reverse(data.begin(), data.end());
		for (int i = 0; i < data.size(); i++)
		{
				if (count % 4 == 0)
				{
						data.insert(data.begin() + i, ',');
				}
				count++;
		}
		data += ",";
		std::map<int, std::string> word = { {4,"billion"},{3,"million"},{2,"thousand"},{1,"hundred"} };
		std::string::size_type index0 = 0;
		std::string::size_type index1 = data.find_first_of(',');
		int c = 1;
		std::string result;
		while (index1 != std::string::npos)
		{
				std::string value = data.substr(index0, index1 - index0);
				std::reverse(value.begin(), value.end());
				while (value.size() < 3) value = "0" + value;
				std::string w = "";
				if (c > 1) w = " " + word[c] + " ";
				result = print(value, map) +  w + result;
				index0 = index1 + 1;
				index1 = data.find_first_of(',', index0);
				c++;
		}
		std::cout << result;
		return 0;
}
1.7 超大数相加
#include <iostream>
#include <string>

int main()
{
		std::string data1, data2;
		std::cin >> data1 >> data2;
		int min = std::min(data1.size(), data2.size());
		int max = std::max(data1.size(), data2.size());
		std::string data;
		data.resize(max + 1, '0');
		for (int i = data1.size() - 1, j = data2.size() - 1, index = 0; i >= 0 && j >= 0; i--, j--, index++)
		{
				int value = (data[index] - '0') + (data1[i] - '0') + (data2[j] - '0');
				int m = value / 10;
				int n = value % 10;
				data[index] = std::to_string(n).back();
				data[index + 1] = std::to_string(m).back();
		}
		for (int i = min; i < max; i++)
		{
				if (i < data1.size())
				{
						int value = (data[i] - '0') + (data1[data1.size() - 1 - i] - '0') ;
						int m = value / 10;
						int n = value % 10;
						data[i] = std::to_string(n).back();
						data[i + 1] = std::to_string(m).back();
				}
				else if(i < data2.size())
				{
						int value = (data[i] - '0') + (data2[data2.size() - 1 - i] - '0');
						int m = value / 10;
						int n = value % 10;
						data[i] = std::to_string(n).back();
						data[i + 1] = std::to_string(m).back();
				}
		}
		int index = data.size() - 1;
		if (data.back() == '0')
		{
				index = data.size() - 2;
		}
		for (int i = index; i >= 0; i--)
		{
				std::cout << data[i];
		}
		return 0;
}

二、复杂度优化

2.1 计算质数因子

2.1.1 一般方法

#include <iostream>
int main()
{
    int number;
    std::cin >> number;
    for (int i = 2; i <= number; i++)
    {
        while (number % i == 0)
        {
            std::cout << i << " ";
            number /= i;
        }
    }
    return 0;
}

2.1.2 采用上述计算方式,运行时间超出要求,需要进行优化,优化后的算法如下,主要在于减少循环次数。

#include <iostream>
#include <cmath>
int main()
{
		int number;
		std::cin >> number;
		while (number % 2 == 0)
		{
				number = number / 2;
				std::cout << 2 << ' ';
		}
		if (number < 2) return 0;
		for (int i = 3; i <= std::sqrt(number); i+=2)
		{
				if (number % i == 0)
				{
						number /= i;
						std::cout << i << ' ';
						i -= 2;
				}
		}
		if (number  > 2) std::cout << number << std::endl;
		return 0;
}

2.1.3 根据质数分布规律优化

#include <iostream>
#include <cmath>
#include <set>

bool isPrime(int value)
{
		if (value == 2 || value == 3)
				return true;
		/*
		* 质数分布规律:
		* 1. 质数一定分布在6的倍数的两侧,如5,7,11,13等;
		* 2. 6的倍数的两侧不一定都是质数。
		*/
		if (value % 6 != 1 && value % 6 != 5)
				return false;
		int size = sqrt(value);
		for (int i = 5; i <= size; i+=6)
		{
				if (value % i == 0 || value % (i + 2) == 0)
						return false;
		}
		return true;
}

int main()
{
		int n = 0;
		std::cin >> n;
		std::set<int> set = { 2 };
		int number = n;
		for (int i = 3; i < n; i++)
		{
				if (isPrime(i))
				{
						set.insert(i);
				}
		}
		int min = number;
		std::pair<int, int> value;
		for (auto& item : set)
		{
				if (set.find(number - item) != set.end())
				{
						if (std::fabs(number - 2 * item) < min)
						{
								min = std::fabs(number - 2 * item);
								value = { std::min(number - item,item),std::max(number - item,item) };
						}
				}
		}
		std::cout << value.first << "\n" << value.second;
}
2.2 排序算法

2.2.1 排序算法,稳定的排序,要求时间O(nlogn),空间O(n)。

https://zhuanlan.zhihu.com/p/36274119

#include <iostream>
#include <vector>
#include <algorithm>
bool compare_1(const std::pair<std::string, std::pair<float, int>>& a, const std::pair<std::string, std::pair<float, int>>& b)
{
		if (a.second.first < b.second.first)
		{
				return true;
		}
		else if (a.second.first == b.second.first && a.second.second < b.second.second)
		{
				return true;
		}
		return false;
}

bool compare_0(const std::pair<std::string, std::pair<float, int>>& a, const std::pair<std::string, std::pair<float, int>>& b)
{
		if (a.second.first > b.second.first)
		{
				return true;
		}
		else if (a.second.first == b.second.first && a.second.second < b.second.second)
		{
				return true;
		}
		return false;
}
int main()
{
		std::vector<std::pair<std::string, std::pair<float, int>>> values;
		int n = 0, m = 0;
		std::cin >> n >> m;
		for (int i = 0; i < n; i++)
		{
				std::pair<std::string, std::pair<float, int>> value;
				std::cin >> value.first >> value.second.first;
				value.second.second = i;
				values.push_back(value);
		}
		if(m == 0)
				std::sort(values.begin(), values.end(), compare_0);
		else if (m == 1)
				std::sort(values.begin(), values.end(), compare_1);

		for (auto& item : values)
		{
				std::cout << item.first << " " << item.second.first << std::endl;
		}
		return 0;
}
2.2 杨辉三角

在这里插入图片描述

#include <iostream>
#include <vector>

int main()
{
		int n = 0;
		std::cin >> n;
		if (n < 3)
		{
				std::cout << "-1";
				return 0;
		}
		std::vector<int> data1 = { 1,1,1 };
		std::vector<int> data2;
		for (int i = 3; i <= n; i++)
		{
				data2.resize(2 * i - 1, 0);
				data2[0] = data2[data2.size() - 1 ] = 1;
				data2[1] = data2[data2.size() - 2] = data1[0] + data1[1];
				for (int k = 2; k <= data2.size() - 3; k++)
				{
						data2[k] = data1[k - 2] + data1[k - 1] + data1[k];
				}
				data1 = data2;
		}
		int index = -1;
		for (int i = 0; i < n; i++)
		{
				if (data2[i] % 2 == 0)
				{
						index =  i + 1;
						break;
				}
		}
		std::cout << index;
		return 0;
}
#include <iostream>
#include <vector>

/*
* 出现偶数的位置规律如下:
* 1----2----3----4----5----6----7----8----9----10----11----12 ...
* 
*-1   -1    2    3    2    4    2    3    2     4    2      3
 */

int getIndex(int n)
{
		if (n < 3) return -1;
		int value = (n - 2) % 4;
		int index = -1;
		switch (value)
		{
		case 1:index = 2; break;
		case 2:index = 3; break;
		case 3:index = 2; break;
		case 0:index = 4; break;
		default: break;
		}
		return index;
}

int main()
{
		int n = 0;
		std::cin >> n;		

		//->找规律
		std::cout << getIndex(n);
		return 0;

		//->常规解法,超时
		if (n < 3)
		{
				std::cout << "-1";
				return 0;
		}
		std::vector<int> data(2 * n - 1, 0);
		data[n - 1] = data[n - 2] = data[n] = 1;
		for (int i = 3; i <= n; i++)
		{
				data[n - i] = data[n + i - 2] = 1;			
				int back2Value = data[n + i - 3];
				int value0 = data[n - i + 1];
				int value1 = 0, value2 = 0;
				data[n - i + 1] =  data[n + i - 3] = data[n - i + 2] + data[n - i + 1];
				for (int k = n - i + 2; k <= n + i - 4; k++)
				{
						value1 = data[k];
						value2 = data[k + 1];
						if (k == n + i - 4)
						{
								value2 = back2Value;
						}
						data[k] = value0 + data[k] + value2;
						value0 = value1;
						value1 = data[k + 1];
				}
		}
		int index = -1;
		for (int i = 0; i < n; i++)
		{
				if (data[i] % 2 == 0)
				{
						index =  i + 1;
						break;
				}
		}
		std::cout << index;
		return 0;
}

三、动态规划

3.1 01背包问题

https://zhuanlan.zhihu.com/p/93857890
https://valen.blog.csdn.net/?type=blog

3.1.1 核心解读
假设物品数量N,限重W的情况下,定义dp[i][j]表示将前i个物品装入限重为j的背包中的最大价值,其中0<=i<=N,0<=j<=W。

  • 当i = 0时,装入背包中的总价值为0,即dp[0][0~W] = 0;
  • 当i > 0时,有如下两种情况:
    • 不装入第i件物品,即[dp[i][j] = dp[i - 1][j];
    • 装入第i件物品,即dp[i][j] = dp[i - 1][j - w[i]] + v[i];

则状态转移方程为:
dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - w[i]] + v[i]),其中j >= w[i]。

3.1.2 对于完全背包问题,即每种物品有无限个,则转移状态方程为:

  • 当i = 0时,装入背包中的总价值为0,即dp[0][0~W] = 0;
  • 当i > 0时,有如下两种情况:
    • 不装入第i件物品,即[dp[i][j] = dp[i - 1][j];
    • 装入第i件物品,即dp[i][j] = dp[i][j - w[i]] + v[i]; 表示装入第i中商品后还可以继续装入第i中商品。

dp[i][j] = max(dp[i - 1][j],dp[i][j - w[i]] + v[i]),其中j >= w[i]。

思路二:01背包问题,装入物品i只有0件和1件,二完全背包问题,装入第i件物品可以取值0,1,W / w[i];因此状态转移方程为:
dp[i][j] = max(dp[i - 1][j],dp[i][j - k * w[i]] + v[i]),其中j >= k* w[i],k<=j /w[i];

3.1.3 例题
在这里插入图片描述在这里插入图片描述

#include <iostream>
#include <map>
#include <vector>

struct Data
{
        int price, nice;
};

int main()
{
        int W = 0, N = 0;
        std::cin >> W >> N;
        std::map<int, std::vector<Data>> product;
        std::map<int, bool> visited;
        for (int i = 0; i < N; i++)
        {
                int price, weight, index;
                std::cin >> price >> weight >> index;
                Data data;
                data.price = price;
                data.nice = price * weight;
                if (index == 0)
                {
                        if (product.find(i) == product.end())
                                product[i].push_back(data);
                        else
                        {
                                product[i].insert(product[i].begin(), data);
                                for (int j = 1; j < product[i].size(); j++)
                                {
                                        Data temp;
                                        temp.price = data.price + product[i][j].price;
                                        temp.nice = data.nice + product[i][j].nice;
                                        product[i][j] = temp;
                                }
                        }
                        visited[i] = true;
                }
                else
                {
                        if (product[index - 1].size() == 0)
                        {
                                product[index - 1].push_back(data);
                                continue;
                        }
                        //->将附件与主件进行组合
                        for (int j = 0, size = product[index - 1].size(); j < size; j++)
                        {
                                Data temp;
                                temp.price = data.price + product[index - 1][j].price;
                                temp.nice = data.nice + product[index - 1][j].nice;
                                product[index - 1].push_back(temp);
                        }
                        if (product[index - 1].size() != 0 && !visited[index - 1])
                        {
                                product[index - 1].push_back(data);
                        }
                }
        }
        //->将商品数量索引与map的it迭代器进行映射
        int index = 0;
        std::map<int, std::map<int, std::vector<Data>>::iterator> mapping;
        for (auto it = product.begin(); it != product.end(); it++)
        {
                mapping[index] = it;
                index++;
        }

        //->核心算法
        std::vector<std::vector<int>> ks(product.size() + 1, std::vector<int>(W + 1, 0));
        for (int i = 1; i < ks.size(); i++)
        {
                for (int j = 0; j < ks[i].size(); j++)
                {
                        for (int k = 0; k < mapping[i - 1]->second.size(); k++)
                        {
                                if (j - mapping[i - 1]->second[k].price >= 0)
                                        ks[i][j] =
                                        std::max(ks[i][j], ks[i - 1][j - mapping[i - 1]->second[k].price] + mapping[i - 1]->second[k].nice);
                                else
                                        ks[i][j] = ks[i - 1][j];
                        }
                }
        }
        std::cout << ks[product.size()][W] << std::endl;
}

四、回溯法

4.1迷宫路径搜索

4.1.1 采用回溯法搜索迷宫中的路径。
在这里插入图片描述
在这里插入图片描述

将数组大小设置(N + 2) x (M + 2), 并设置最外围为1,简化代码判断逻辑。

#include<vector>
#include <iostream>
#include <stack>

bool FindPath(std::vector<std::vector<int>>& data, std::vector<std::vector<int>>& mark, int x, int y, int i, int j, std::stack<std::pair<int,int>>& path)
{
		if (x == i && y == j)
				return true;
		std::vector<std::pair<int, int>> move = { {-1,0},{1,0},{0,-1},{0,1} };
		for (int k = 0; k < move.size(); k++)
		{
				int next_i = i + move[k].first;
				int next_j = j + move[k].second;
				if (data[next_i][next_j] == 0 && mark[next_i][next_j] == 0)
				{
						mark[next_i][next_j] = 1;
						if (FindPath(data, mark, x, y, next_i, next_j,path))
						{
								path.push({ next_i,next_j });
								return true;
						}
				}
		}
		if (x == 1 && y == 1)
				return false;
		return  false;;
}

int main()
{
		int n = 0, m = 0;
		std::cin >> n >> m;
		std::vector<std::vector<int>> data = std::vector<std::vector<int>>(n + 2, std::vector<int>(m + 2, 1));
		std::vector<std::vector<int>> mark = std::vector<std::vector<int>>(n + 2, std::vector<int>(m + 2, 0));
		for (int i = 1; i <= n; i++)
		{
				for (int j = 1; j <= m; j++)
				{
						std::cin >> data[i][j];
				}
		}
		std::stack<std::pair<int, int>> path;
		mark[1][1] = 1;
		int value = FindPath(data, mark, n, m, 1, 1, path);
		path.push({ 1,1 });
		while (!path.empty())
		{
				std::pair<int, int> node = path.top();
				std::cout << "(" << node.first - 1 << "," << node.second - 1 << ")" << std::endl;
				path.pop();
		}
		return 0;
}
4.2 九宫格游戏
#include<vector>
#include <iostream>

bool row(std::vector<std::vector<int>>& data, int i, int value)
{
		for (int k = 0; k < 9; k++)
		{
				if (data[i][k] == value) return false;
		}
		return true;
}

bool col(std::vector<std::vector<int>>& data, int j, int value)
{
		for (int k = 0; k < 9; k++)
		{
				if (data[k][j] == value) return false;
		}
		return true;
}

bool region(std::vector<std::vector<int>>& data, int i, int j, int value)
{
		int istart = i / 3 * 3;
		int jstart = j / 3 * 3;
		for (int m = istart; m < istart + 3; m++)
		{
				for (int n = jstart; n < jstart + 3; n++)
				{
						if (data[m][n] == value)
								return false;
				}
		}
		return true;
}

void output(std::vector<std::vector<int>>& data)
{
		for (int i = 0; i < 9; i++)
		{
				for (int j = 0; j < 9; j++)
				{
						std::cout << data[i][j] << " ";
				}
				std::cout << std::endl;
		}
		// 调试用
		//std::cout << std::endl;
		//std::system("pause");
}

bool FindNumber(std::vector<std::vector<int>>& data, int index, std::vector<std::pair<int,int>>& position, std::vector<bool>& visited)
{
		if (index == position.size())
				return true;
		if (index < 0 || index > position.size())
				return false;
		std::vector<int> values;
		for (int v = 1; v <= 9; v++)
		{
				if (!row(data, position[index].first, v))
						continue;
				if (!col(data, position[index].second, v))
						continue;
				if (!region(data, position[index].first, position[index].second, v))
						continue;
				values.push_back(v);
		}
		if (values.empty() && index < position.size())
				return false;

		int count = 0;
		for (auto& v : values)
		{
				data[position[index].first][position[index].second] = v;
				//output(data);
				if (FindNumber(data, index + 1, position, visited))
				{
						data[position[index].first][position[index].second] = v;
						return true;
				}
				else
				{
						count++;
				}
		}
		if (count == values.size())
		{
				data[position[index].first][position[index].second] = 0;
				return false;
		}
		return true;
}

int main()
{
		/*
		 0 9 5 0 2 0 0 6 0 
		 0 0 7 1 0 3 9 0 2 
		 6 0 0 0 0 5 3 0 4 
		 0 4 0 0 1 0 6 0 7 
		 5 0 0 2 0 7 0 0 9
		 7 0 3 0 9 0 0 2 0
		 0 0 9 8 0 0 0 0 6
		 8 0 6 3 0 2 1 0 5 
		 0 5 0 0 7 0 2 8 3
		*/
		std::vector<std::vector<int>> data = std::vector<std::vector<int>>(9, std::vector<int>(9, 0));
		std::vector<std::pair<int, int>> position;
		std::vector<bool> visited;
		for (int i = 0; i < 9; i++)
		{
				for (int j = 0; j < 9; j++)
				{
						std::cin >> data[i][j];
						if (data[i][j] == 0)
						{
								position.push_back({ i,j });
								visited.push_back(false);
						}
				}
		}
		bool value = false;
		for (int i = 0; i < position.size(); i++)
		{
				value = FindNumber(data, 0, position, visited);
				if (value) break;
		}
		output(data);
		return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秘境之眼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值