数据结构题目汇总

2023-11-09

求整数最大间隔-性能(hash算法应用)

题目描述
请输出数字序列的最大间隔。
请使用以下伪随机数生成函数 rand32 () 生成伪随机数
int seed ;
int rand(){ return((( seed = seed * 214013L + 2531011L) >> 16) & 0x7fff); }
int rand32(){
return ((rand() << 16) + (rand() << 1) + rand() % 2);
}
Input Format
2个整数,n seed 其中 2<n<=20000000,seed为随机数种子。
Output Format
整数序列的最大间隔
Example
Input
2000000
1
Output
15737

样例
输入:
1959000 4910
输出:
16709
注意:O(nlogn)以上的时间复杂度至少会有一个案例超时。

#include<iostream>
#include<string.h>
using namespace std;

int n,seed;
int randI() {
	return(((seed = seed * 214013L + 2531011L) >> 16) & 0x7fff);
}
int rand32() {
	return ((randI() << 16) + (randI() << 1) + randI() % 2);
}
int maxGap(int arr[]) {
	int minN = arr[0], maxN = arr[0]; 
	//遍历找到数组中最大值最小值。 
	for (int i = 0; i < n; ++i) 
	{
		if (arr[i] > maxN)maxN = arr[i];
		if (arr[i] < minN)minN = arr[i];
	}
	if (maxN == minN)return 0;
    //构造n+1个桶。 
	bool* hasNum = new bool[n + 1];
	memset(hasNum, 0, sizeof(bool) * (n + 1));
	int* mins = new int[n + 1];
	int* maxs = new int[n + 1];
	//遍历数组 找到每个桶中max min。 
	for (int i = 0; i < n; ++i) 
	{
		//double gap = double(maxN - minN + 1) / (n + 1);
		double gap = double(maxN - minN) / (n - 1);
		int index = int((arr[i] - minN) / gap); //几号桶。  
		if (!hasNum[index])  
		{
			mins[index] = maxs[index] = arr[i];
			hasNum[index] = true;
		}
		else 
		{
			mins[index] = min(arr[i], mins[index]);
			maxs[index] = max(arr[i], maxs[index]);
		}
	}

	int maxGap = 0;
	int lastMax = maxs[0];
	for (int i = 1; i <= n; i++) 
	{
		if (hasNum[i]) //不是空桶。 
		{
			maxGap = max(maxGap, (mins[i] - lastMax));
			//cout << mins[i] << ' ' << lastMax << endl;
			lastMax = maxs[i];
		}
	}

	delete[]hasNum;
	delete[]maxs;
	delete[]mins;
	return maxGap;
}
int main() {
	cin >> n >> seed;
	int* arr = new int[n];
	for (int i = 0; i < n; ++i)
		arr[i] = rand32();
	cout << maxGap(arr) << endl;
	delete[]arr;
	return 0;
}

linux路径(栈应用)

题目描述
给定一个非最简的Linux文件绝对路径,将其简化为标准的Linux文件绝对路径。
在Linux文件路径中,一个英文句号 . 表示当前目录,两个连续的英文句号 … 表示返回到上一级目录。
标准的Linux文件绝对路径具有以下特点
第一个字符为斜杠 /
两个目录名称直接有且仅有一个斜杠 /
除根目录外,路径结尾不能为斜杠 /
不会出现一个英文句号 . 或者两个连续的英文句号 …
Input Format
输入由一行字符串组成,为非最简的Linux文件绝对路径。
Output Format
输出一行,为最简化的Linux文件绝对路径。
Example
Input
/aaa/…/…/bbb/ccc/…///./…
Output
/
说明
路径从根目录开始从左往右进行解析
aaa 表示进入根目录下 aaa 目录
… 表示返回上一级目录,即返回根目录
… 表示返回上一级目录,但当前目录为根目录,无上一级目录。故仍处于根目录。
bbb 表示进入根目录下 bbb 目录
ccc 表示进入 bbb 目录下 ccc 目录
… 表示返回上一级目录,即返回 bbb 目录
后续若干个连续的斜杠 / 间没有目录名称,直接删除
. 表示当期文件夹,故仍处于 bbb 目录
… 表示返回上一级目录,即返回根目录
根目录用斜杠 / 表示,故输出斜杠 /

样例1
输入:
/aaa/…/…/bbb/ccc/…///./…
输出:
/
样例2
输入:
/home/
输出:
/home

#include <iostream>
#include <string>
#include <stack>
using namespace std;
string simplifyPath(string path) 
{
    stack<string> temp;
    int i=0,j=0;
    while(i<path.size()-1)
    {
        j=i+1;
        //读取一个完整的目录名称。
        while(path[j] != '/') ++j;
        if(i+1 == j)
        {
            i=j;
            continue;
        }
        string s=path.substr(i,j-i);

        if("/." == s)
        {
            i=j;
            continue;
        }
        if("/..." == s && !temp.empty())  temp.pop();
        else if("/..." == s && temp.empty()) ;
        else 
            temp.push(s);
        i=j;
    }
    if(temp.empty()) return "/";
    else
    {
        string res;
        while(!temp.empty())
        {
            res=temp.top()+res;
            temp.pop();
        }
        return res;
    }
}
int main()
{
    string s;
    cin>>s;
    cout<<simplifyPath(s);
}


二元一次多项式求幂(队列)

题目描述
给定一个常数项为0的二元一次多项式,求该多项式的幂。
设未知数为x,y,输入为x和y的整数系数a,b以及整数幂n,输出形如以下样式
求幂运算的结果,按照x的幂降序排列
Input Format
输入未知数整数系数 a,b (-100<a,b<100),n (1<n<6)
Output Format
幂运算的结果的多项式,按照x幂降序排列
Example
Input
2 3 2
Output
4x^2+12xy+ 9y ^2
说明
幂为1时不输出^1
系数为1时不输出系数,-1只输出负号。

样例输入输出
样例1
输入:
2 3 2
输出:
4x^2+12xy+ 9y ^2

#include <iostream>
#include <queue>
using namespace std;
int main()
{
	long long a,b;
	long long t,w;
	int x,y,n;
	cin >> a >> b >> n;
	x = n;
	y = 0;
	queue <long long> q;
	q.push(0);
	q.push(a);
	q.push(b);
	for (int i = 1 ; i < n ; i++)
	{
		q.push(0);
		for (int j = 1 ; j <= i + 2 ; j++)
		{
			t = q.front();
			q.pop();
			w = q.front();
			q.push(b * t + a * w);//计算系数,利用杨辉三角 
			 
		}
	}
	q.pop();
	while (!q.empty())
	{
		if(q.front() == 1){}
		else if(q.front() == -1)
		{
			cout << "-";
		}
		else
		{
			cout << q.front();
		}
		if (x == 1)
		{
			cout << "x";
		}
		else if (x == 0){}
		else
		{
			cout << "x^" <<x;
		}
		if (y == 1)
		{
			cout << "y";
		}
		else if (y == 0){}
		else
		{
			cout << "y^" << y;
		}
		x--;
		y++;
		
		q.pop();
		if (!q.empty() && q.front() > 0)
		cout << "+";
	}
	 
}

二元一次多项式的幂(大整数)

题目描述
给定一个常数项为0的二元一次多项式,求该多项式的幂。

设未知数为x,y,输入为x和y的整数系数a,b以及整数幂n,输出形如以下样式

求幂运算的结果,按照x的幂降序排列

Input Format
输入未知数整数系数 a,b (-1000<a,b<1000),n (2<n<20)

Output Format
幂运算的结果的多项式,按照x幂降序排列

Example
Input
99 100 15
Output
860058354641288524893953951499x15+13031187191534674619605362901500x14y+92139707414891638724482363950000x13y2+403305116630838822699754455000000x12y3+1222136717063147947575013500000000x11y4+2715859371251439883500030000000000x10y5+4572153823655622699495000000000000x9y6+5937862108643665843500000000000000x8y7+5997840513781480650000000000000000x7y8+4712108147752005000000000000000000x6y9+2855823119849700000000000000000000x5y10+1311213553650000000000000000000000x4y11+441486045000000000000000000000000x3y12+102910500000000000000000000000000x2y13+14850000000000000000000000000000xy14+1000000000000000000000000000000y15
说明
幂为1时不输出^1
系数为1时不输出系数,-1只输出负号。

#include<iostream>
#include<queue>
#include<string>
#include<string.h>
using namespace std;

//将数字的非符号部分存入字符串 
string getNum(const string& s) {
	int t = s.size();
	string str = "";
	if (s[0] == '-')
	{
		for (int i = 1; i < t; i++)
		    str += s[i];
	}
	else
	{
		for (int i = 0; i < t; i++)
		    str += s[i];
	}
	return str;
}

//乘法,逐位计算,将结果存入数组再转为字符串 
string multi(const string& a, const string& b) 
{
	int len1, len2;
	int isNeg = 0;
	if (((a[0] == '-' && b[0] != '-') || (a[0] != '-' && b[0] == '-')) && (a != "0" && b != "0")) isNeg = 1;
	string num1 = getNum(a);
	string num2 = getNum(b);
	len1 = num1.size();
	len2 = num2.size();

	int* res = new int[len1 + len2];
	memset(res, 0, sizeof(int) * (len1 + len2));


	for (int i = len1 - 1; i >= 0; --i) 
	{
		for (int j = len2 - 1; j >= 0; --j) {
			res[i + j + 1] += (num1[i] - '0') * (num2[j] - '0');
		}
	}
	for (int i = len1 + len2 - 1; i >= 0; --i) 
	{
		if (res[i] >= 10) {
			res[i - 1] += res[i] / 10;
			res[i] %= 10;
		}
	}
	string ans = "";
	for (int i = 0; i < len1 + len2; ++i) ans += res[i] + '0';
	if (isNeg) ans = '-' + ans;
	return ans;
}

//加法 
string plusNum(const string& num1, const string& num2) 
{
	int len1 = num1.size(), len2 = num2.size();
	int len = max(len1, len2) + 1;
	int length = len;
	string ans = "";
	int* res = new int[length]; 
	memset(res, 0, sizeof(int) * length);

	while (len1 > 0 && len2 > 0) 
	{
		res[len - 1] = (num1[len1 - 1] - '0') + (num2[len2 - 1] - '0');
		len1--;
		len2--;
		len--;
	}
	while (len1 > 0) 
	{
		res[len - 1] = (num1[len1 - 1] - '0');
		len1--;
		len--;
	}
	while (len2 > 0) 
	{
		res[len - 1] = (num2[len2 - 1] - '0');
		len2--;
		len--;
	}
	for (int i = length - 1; i >= 0; --i) 
	{
		if (res[i] >= 10) 
		{
			res[i - 1] += res[i] / 10;
			res[i] %= 10;
		}
	}

	int k;
	for (k = 0; k < length; k++)
		if (res[k] != 0)break;
	if (k == length)ans = "0";
	else 
	{
		for (int i = k; i < length; i++)
			ans += res[i] + '0';
	}
	return ans;
}

//减法 
string minusNum(string& num1, string& num2) 
{
	int len1 = num1.size();
	int len2 = num2.size();
	int len;
	if (len1 >= len2) 
	{
		for (int i = 1; i <= len1 - len2; i++)
			num2 = '0' + num2;
		len = len1;
	}
	if (len2 > len1) 
	{
		for (int i = 1; i <= len2 - len1; i++)
			num1 = '0' + num1;
		len = len2;
	}

	int* num_a = new int[len];
	int* num_b = new int[len];
	for (int i = 0; i < len; ++i) 
	{
		num_a[i] = num1[i] - '0';
		num_b[i] = num2[i] - '0';
	}
	int q = 0;//记录退位 
	for (int i = len - 1; i >= 0; --i) 
	{
		num_a[i] -= q;
		if (num_a[i] < num_b[i]) {
			num_a[i] += 10;
			q = 1;
		}
		num_b[i] = num_a[i] - num_b[i];
	}
	
	int k;
	string ans = "";
	for (k = 0; k < len; k++)
		if (num_b[k] != 0)break;
	if (k == len)ans = "0";
	else 
	{
		for (int i = k; i < len; i++)
			ans += num_b[i] + '0';
	}
	return ans;
}

//判断两数相减结果是否为非负 
bool isPos(const string&str1, const string str2) 
{
	if (str1.size() > str2.size())
		return true;
	if (str1.size() == str2.size())
		return str1 > str2;
	return false;
}

//计算系数 
void powerFun(queue<string>& q, int n, const string& a, const string& b) 
{
	string t = "0";
	string s;
	string num1, num2;
	string ans;
	for (int i = 2; i <= n; i++) 
	{
		q.push(to_string(0));
		for (int j = 1; j <= i + 1; j++) 
		{
			s = q.front();
			q.pop();
			
			num1 = multi(t, b);
			num2 = multi(s, a);
			if (num1[0] != '-' && num2[0] != '-')
				ans = plusNum(num1, num2);
			else if (num1[0] == '-' && num2[0] == '-') 
			{
				ans = plusNum(getNum(num1), getNum(num2));
				ans = '-' + ans;
			}
			if (num1[0] == '-' && num2[0] != '-') 
			{
				num1 = getNum(num1);
				if (isPos(num2, num1)) 
				{
					ans = minusNum(num2, num1);
				}
				else 
				{
					ans = '-' + minusNum(num1, num2);
				}
			}
			if (num1[0] != '-' && num2[0] == '-') 
			{
				num2 = getNum(num2);
				if (isPos(num1, num2)) 
				{
					ans = minusNum(num1, num2);
				}
				else 
				{
					ans = '-' + minusNum(num2, num1);
				}
			}
			q.push(ans);
			t = s;
		}
	}
}

//表达式输出处理 
void showRes(queue<string>& q, int n) 
{
	int k = n;
	int flag = 1;
	while (!q.empty()) 
	{
		if (q.front() == "0" ) 
		{
			q.pop();
			k--;
			flag = 0;
			continue;
		}
		else if (q.front() == "1") 
		{
			if (flag != 0 && k < n)cout << '+';
			flag = 1;
		}
		else if (q.front()[0] != '-') 
		{
			if (k < n)cout << '+';
			cout << q.front();
		}
		else if (q.front() == "-1") cout << '-';
		else if (q.front()[0] == '-') cout << q.front();

		if (k == 1) cout << 'x';
		else if (k != 0) cout << "x^" << k;
		if (k == n - 1) cout << 'y';
		else if (k != n) cout << "y^" << n - k;

		q.pop();
		k--;
	}
	cout << endl;
}



int main() 
{
	int a, b, n;
	cin >> a >> b >> n;
	queue<string>q;
	string str1 = to_string(a);
	string str2 = to_string(b);
	q.push(str1);
	q.push(str2);
	powerFun(q, n, str1, str2);
	showRes(q, n);
	return 0;
}

二叉树遍历及二叉树高度

题目描述
给出一棵二叉树的先序遍历和中序遍历序列,计算该二叉树的高度。其中,二叉树的先序和中序遍历序列为不包含重复英文字母(区别大小写)的字符串。
Input Format
二叉树结点的总个数n<=50
然后输入先序和中序遍历序列,两个序列长度均为n。
Output Format
二叉树高度(整数) ,叶子结点高度为1

Example
Input
9
ABDGHCEIF
GDHBAEICF
Output
4

#include<iostream>
using namespace std;
 
int GetHeight(char* pre,char* in,int n)   //求二叉树的高度
{
    if(n == 0)    //若没有结点,为空树
    {
        return 0;
    }
    int i;
    for(i = 0; i < n; i++)
    {
        if(in[i] == pre[0])  //找到根结点在中序的位置
        {
            break;
        }
    }
    int left = GetHeight(pre + 1, in, i);  //左子树的深度
    int right = GetHeight(pre + i + 1, in + i + 1, n - i - 1);   //右子树的深度
    return max(left, right) + 1;  //返回左右子树深度的较大值中的较大值+根结点
}
int main()
{
    int n;
    cin >> n;
    char pre[n + 1], in[n + 1];  //先序和中序
    cin >> pre >> in;
    cout << GetHeight(pre, in, n) << endl;
    return 0;
}


 

创建AVL树并判断是否为完全二叉树

题目描述
在AVL树中,任何节点的两个子树的高度最多相差1;如果它们高度相差不止1,则需要重新平衡以恢复这种属性。
现在给定一个插入序列, 一个一个地将键值插入初始为空的AVL树中,输出得到的AVL树的层次顺序遍历序列,并判断它是否是一个完全二叉树。

输入格式:

第一行包含一个正整数N(<= 20)。然后在下一行给出N个不同的整数键。所有数字都用空格隔开。

输出格式:

第一行打印得到的AVL树的层次顺序遍历序列。所有数字都必须用空格隔开,并且行尾必须没有多余的空格。然后在下一行中,如果树为完全二叉树,则打印“Yes”;如果不是,则打印“No”。

样例1
输入:
5
88 70 61 63 65

输出:
70 63 88 61 65
Yes

样例2
输入:
10
62 88 58 47 35 73 51 99 37 93

输出:
62 47 88 35 58 73 99 37 51 93
No

#include <queue>
#include <vector>
#include <iostream>
using namespace std;
typedef struct AVLNode
{
	struct AVLNode *left,*right;
	int val,height;
}*Node;
int getHeight(Node root)
{
	if(root == NULL)	return 0;
	else	return root->height;
}
Node rightrotate(Node root)
{
	Node tmp = root->left;
	root->left = tmp->right;
	tmp->right = root;
	root->height = max(getHeight(root->left),getHeight(root->right)) + 1;
	tmp->height = max(getHeight(tmp->left),getHeight(tmp->right)) + 1;
	return tmp;
}
Node leftrotate(Node root)
{
	Node tmp = root->right;
	root->right = tmp->left;
	tmp->left = root;
	root->height = max(getHeight(root->left),getHeight(root->right)) + 1;
	tmp->height = max(getHeight(tmp->left),getHeight(tmp->right)) + 1;
	return tmp;
}
Node rightleftrotate(Node root)
{
	root->right = rightrotate(root->right);
	return leftrotate(root);
}
Node leftrightrotate(Node root)
{
	root->left = leftrotate(root->left);
	return rightrotate(root);
}
Node insert(Node root,int key)
{
	if(root == NULL)
	{
		root = new AVLNode();
		root->val = key;
		root->left = root->right = NULL;
		root->height = 1;
		return root;
	}
	else
	{
		if(key < root->val)
		{
			root->left = insert(root->left, key);
			if(getHeight(root->left) - getHeight(root->right) == 2)
			{
				if(key < root->left->val)	root = rightrotate(root);
				else root = leftrightrotate(root);
			}
		}
		else if(key > root->val)
		{
			root->right = insert(root->right, key);
			if(getHeight(root->right) - getHeight(root->left) == 2)
			{
				if(key > root->right->val)	root = leftrotate(root);
				else root = rightleftrotate(root);
			}
		}
	}
	root->height = max(getHeight(root->left),getHeight(root->right)) + 1;
	return root;
}
void level_order_traverse(Node root)
{
	queue<Node>q;
	vector<int>ans;
	q.push(root);
	bool flag = false,flag2 = false;
	while(!q.empty())
	{
		Node p = q.front();	
		q.pop();
		ans.push_back(p->val);
		if(p->left != NULL)
		{
			q.push(p->left);
			if(flag)	flag2 = true;
		}
		else	flag = true;
 
		if(p->right != NULL)
		{
			q.push(p->right);
			if(flag)	flag2 = true;
		}
		else flag = true;
	}
	for(int i = 0; i < ans.size(); i++)
	{
		if(i == ans.size() - 1)	cout << ans[i] << endl;
		else	cout << ans[i] << ' ';
	}
	if(!flag2)	cout << "Yes" << endl;
	else cout << "No" << endl;
}
int main()
{
	int n;
    cin >> n;
	Node root = NULL;
	for(int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;
		root = insert(root, x);
	}
	level_order_traverse(root);
 
	return 0;
}

判断是否为堆

题目描述
请判断输入的整数序列是否为堆。
如果为最大堆,请输出“max ”以及整理后的最小堆,整数序列数字之间有空格,最后无空格。
如果为最小堆,请输出“min ” 以及整理后的最大堆,整数序列数字之间有空格,最后无空格。
如果不为堆,请输出整理后的最大堆,整数序列数字之间有空格,最后无空格。
如果既是最大堆也是最小堆,请只输出“max min ”
Input Format
先输入整数序列个数n 0<n<1000
然后输入n个整数序列,整数取值范围【-100000,100000】
Output Format
最大堆或最小堆序列

Example
Input
10
-8 8 -9 10 -2 1 -6 -9 7 2
Output
10 8 1 7 2 -9 -6 -9 -8 -2

Input
10
10 8 1 7 2 -9 -6 -9 -8 -2
Output
max -9 -9 -6 -8 -2 1 10 7 8 2

Input
10
-9 -9 -6 -8 -2 1 10 7 8 2
Output
min 10 8 1 7 2 -9 -6 -9 -8 -2

Input
3
1 1 1
Output
max min

注意:序列最后无空格,max和min后面均有空格。
如案例,定义以下实现约束:两个相等子节点情况下,整理过程中,父节点下沉时,选择右沉。
10
10 8 1 7 2 -9 -6 -9 -8 -2
两个相等子节点情况下,整理过程中,父节点下沉时,选择右沉。

#include<iostream>
using namespace std;
int flag = 0; 
void IsHeap(int num[], int n) 
{
	bool isMax = true, isMin = true;
	int lChild, rChild;
	for (int i = 1; i <= n; ++i) 
	{
		lChild = i * 2;
		rChild = i * 2 + 1;
		if (rChild <= n) 
		{
			if (num[i] == num[lChild] && num[i] == num[rChild])continue;//结点与孩子相等,可以是最大堆也可以是最小堆。 
			else if (num[i] <= num[lChild] && num[i] <= num[rChild])//结点的左右孩子都不比它小,故不是最大堆。 
				isMax = false;
			else if (num[i] >= num[lChild] && num[i] >= num[rChild])//结点的左右孩子都不比它大,故不是最小堆。 
				isMin = false;
			else
			{
				isMax = isMin = false;
				break;
			}
		}
		else if (lChild <= n) 
		{
			if (num[i] == num[lChild])continue;
			else if (num[i] < num[lChild])
				isMax = false;
			else if (num[i] > num[lChild])
				isMin = false;
			else 
			{
				isMax = isMin = false;
				break;
			}
		}
	}
	//四种结果 
	if (isMax == true) 
	{
		if (isMin == false)flag = 1;
		if (isMin == true)flag = 3;
	}
	else 
	{
		if (isMin == true)flag = 2;
		if (isMin == false)flag = 4;
	}
}
void BuildMaxHeap(int num[], int n) //生成最大堆 
{
	for (int i = n / 2; i >= 1; --i) 
	{
		int t = num[i];//结点 
		int c = i * 2;//左孩子 
		while (c <= n) 
		{
			if (c < n && num[c] <= num[c + 1])
				c++;
			if (t < num[c]) //结点小于右孩子
			{
				num[c / 2] = num[c];//将右孩子的值赋给结点 
				c *= 2;//到下一层 
			}
			else break;
		}
		num[c / 2] = t;//将原结点的值赋给右孩子 
	}
}

void BuildMinHeap(int num[], int n) //生成最小堆 
{
	for (int i = n / 2; i >= 1; --i) 
	{
		int t = num[i];
		int c = i * 2;
		while (c <= n) 
		{
			if (c < n && num[c] >= num[c + 1])
				c++;
			if (t > num[c]) 
			{
				num[c / 2] = num[c];
				c *= 2;
			}
			else break;
		}
		num[c / 2] = t;
	}
}
void BuildHeap(int num[], int n) 
{

	if (flag == 1) 
	{
		cout << "max ";
		BuildMinHeap(num, n);
	}
	if (flag == 2) 
	{
		cout << "min ";
		BuildMaxHeap(num, n);
	}
	if (flag == 3) 
	{
		cout << "max min" << endl;
		return;
	}
	if (flag == 4) 
	{
		BuildMaxHeap(num, n);
	}
	for (int i = 1; i <= n; ++i) 
	{
		if (i == n)cout << num[i];
		else cout << num[i] << " ";
	}
}
int main() {
	int n, num1[1001];
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> num1[i];
	IsHeap(num1, n);
	BuildHeap(num1, n);
	return 0;
}

消除连通图多余的边

在这里插入图片描述

样例
输入:
5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2
输出:
8

#include<iostream>
#include<algorithm>
using namespace std;

//用kruskal算法计算留下的边权重和,再用总权重减掉剩下的边的权重得到去除边的权重和。 
struct Edge 
{
	int u, v, w;
	bool operator <(struct Edge& edge) //因为要用sort()进行排序,重载运算符'<'。 
	{
		return w < edge.w;
	}
}e[10005];
int n, m, par[10005];
int unionfind(int x) //查找元素的根节点。 
{
	return x == par[x] ? x : par[x] = unionfind(par[x]);
}

int kruskal() 
{
	int cnt = 0, ans = 0;
	sort(e, e + m);
	for (int i = 0; i < m; ++i) 
	{
		int fu = unionfind(e[i].u), fv = unionfind(e[i].v);
		if (fu != fv) //根节点不同。 
		{
			ans += e[i].w;
			par[fu] = fv;
			if (++cnt == n - 1)return ans;// 已有n-1条边。 
		}
	}
}
int main() 
{
	int sum = 0;
	cin >> n >> m;
	for (int i = 0; i < m; i++) 
	{
		cin >> e[i].u >> e[i].v >> e[i].w;
		sum += e[i].w;
	}
	for (int i = 1; i <= n; i++)
		par[i] = i;
	cout << sum - kruskal() << endl;
}

旋转的矩阵

在这里插入图片描述

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int m, n;
    while(cin >> m >> n)
    {
        vector<vector<int>> res(m, vector<int>(n));
        /*定义了一个vector容器,元素类型为vector<int>,
		初始化为包含m个vector<int>对象,
		每个对象都是一个新创立的vector<int>对象的拷贝,
		而这个新创立的vector<int>对象被初始化为包含n个0。*/
        for(int i = 0; i < m; i++)
        {
        	for (int j = 0; j < n; j++) cin >> res[i][j];
		}

        int row = res.size();
        int col = res[0].size();
        int left = 0, right = col-1, top = 0, bottom = row-1;
        vector<int> s;
        
        while(left <= right && top <= bottom) 
        {
        	//顺时针。 
            for(int i = left; i <= right; i++) s.push_back(res[top][i]);

            for(int i = top + 1; i <= bottom; i++) s.push_back(res[i][right]); 
			   
            if(top != bottom)
            {
                 for(int i = right - 1; i >= left; i--) s.push_back(res[bottom][i]);    
            }

            if(left != right)
            {
                 for(int i = bottom - 1;i >= top + 1 ; i--) s.push_back(res[i][left]);    
            }
            left++, top++, right--, bottom--;
            
            //逆时针。 
            if(left < right && top < bottom)
            {
				for(int i = top; i <= bottom ; i++) s.push_back(res[i][left]);
	            
	            for(int i = left + 1; i <= right ; i++) s.push_back(res[right-1][i]);
	            
	            if(left != right)
	            {
	            	for(int i = bottom - 1; i >= top; i--) s.push_back(res[i][right]);
				}
				if(top != bottom)
				{
					for(int i = right - 1; i >= left + 1; i--) s.push_back(res[top][i]);
				}
				left++, top++, right--, bottom--;
			}
        }
        for(int i = 0; i < s.size(); i++)
        {
            if (i == s.size() - 1)
                cout << s[i] << endl;
            else
                cout << s[i] << ' ';
        }
        
    }
    return 0;
}


Example
Input
4 4
1 2 3 4
12 13 16 5
11 14 15 6
10 9 8 7
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Input
3 4
1 2 3 4
10 11 12 5
9 8 7 6
Output
1 2 3 4 5 6 7 8 9 10 11 12

完全二叉树的先序遍历

题目描述
给出一棵完全二叉树的先序遍历,输出其后序遍历。结点均为不重复的单个英文字母,区分大小写。结点总数小于52。

Input Format

输入先序字符串

Output Format 后序遍历字符串

Example Input ABDGHCEIF

Output GHDCBIFEA

附件
样例1
输入:
ABDGHCEIF
输出:
GHDCBIFEA
样例2
输入:
a
输出:
a

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
class node 
{
public:
	node* lChild;
	node* rChild;
	char value;
	node(char v = NULL, node* l = NULL, node* r = NULL) 
	{
		value = v;
		lChild = l;
		rChild = r;
	}
	
};
void postorder(node* Tree) 
{
	if (Tree == NULL) 
	{
		return;
	}
	else 
	{
		postorder(Tree->lChild);
		postorder(Tree->rChild);
		cout << Tree->value;
	}
}

int main() 
{
	string s;
	cin >> s;
	node* Tree = new node[s.size() + 1];//Tree[0]没有用到,从1开始。 
	int n = 1;
	int m = 1;
	//求s为满二叉树时的元素个数m。 
	while ((int)s.size() > m) 
	{
		double u = (double)n;
		m += pow(2, u);
		n++;
	}
	for (int q = 1; q <= s.size(); q++) 
	{
		if (2 * q <= (int)s.size()) Tree[q].lChild = &Tree[2 * q];
		if (2 * q + 1 <= (int)s.size()) Tree[q].rChild = &Tree[2 * q + 1];
	}
	Tree[1].value = s[0];
	for (int i = 1, j = 1; i < (int)s.size();) 
	{
		while (Tree[j].value != NULL && Tree[j].lChild != NULL && i < (int)s.size()) 
		{
			j = 2 * j;
			Tree[j].value = s[i++];

		}
		if (Tree[j / 2].rChild != NULL && Tree[j / 2].rChild->value == NULL) 
		{
			j = j + 1;
			Tree[j].value = s[i++];
		}
		else if (Tree[j / 2].rChild != NULL && Tree[j / 2].rChild->value != NULL) 
		{
			j = j / 2;
			while (j > 1 && Tree[j / 2].rChild != NULL && Tree[j / 2].rChild->value != NULL) j = j / 2;
			j = j + 1;
			Tree[j].value = s[i++];
		}
		else if (Tree[j / 2].rChild == NULL) 
		{
			j = j / 2 ;
			while (j > 1 && Tree[j / 2].rChild != NULL && Tree[j / 2].rChild->value != NULL) j = j / 2;
			j = j + 1;
			Tree[j].value = s[i++];
		}
	}
	postorder(&Tree[1]);
	delete[]Tree;
	return 0;
}

Dijkstra单源最短路径

在这里插入图片描述

样例
输入:
8 10
1 6 10
1 5 5
6 3 1
6 5 2
3 4 4
4 1 7
4 3 6
5 6 3
5 3 9
5 4 2
1
输出:
No.1 : 1 -> 5 , d = 5
No.2 : 1 -> 5 -> 4 , d = 7
No.3 : 1 -> 5 -> 6 , d = 8
No.4 : 1 -> 5 -> 6 -> 3 , d = 9
No.5 : No Path to 2 7 8

#include<iostream>
#include<stack>

using namespace std;

struct edge
{
	int bg, ed, val;
	edge(int p = 0,int q = 0,int v = -1):bg(p), ed(q), val(v){}
};

struct Node
{
	int flag;//标示结点是否已被访问。 
	Node(int f = 0):flag(f){}
};
//存储距离该结点最近的点以及路径长 
struct path
{
	int length, k;
	path(int l = 101,int kk = 0):length(l),k(kk){}
	path(const path& p)
	{
		length = p.length;
		k = p.k;
	}
};
//得到距离该点最近的点的路径长度 
int minpath(int bg, int ed, edge* e, int m)
{
	if(bg == ed)return 0;
	int min = 101;
	for(int i = 0;i < m; i++)
		if(e[i].bg == bg && e[i].ed == ed && e[i].val < min)
			min = e[i].val;

		return min;
}

int main()
{
	int n, m, t1, t2, t3, s;
	cin >> n >> m;
	edge* e = new edge[m];
	Node* N = new Node[n];
	int* pre = new int[n];//与当前结点相连的前一个点。 
	path* p = new path[n];
    
   
	for(int i = 0; i < n; i++)
		p[i].k = i;

	for(int i = 0; i < n; i++)
		pre[i] = -1;

	for(int i = 0; i < m; i++)
	{
		cin >> t1 >> t2 >> t3;
		e[i].bg = t1 - 1;
		e[i].ed = t2 - 1;
		e[i].val = t3;
	}
	cin >> s;
	s -= 1;
	pre[s] = s;
	p[s].length = 0;
	N[s].flag = 1;

	int* key = new int[n];
	for(int i = 0; i < n; i++)
	{
		p[i].length = minpath(s, i, e, m);
		key[i] = p[i].length;//暂存各结点的最短路径。 
	}

	int c1, c2;
	c1 = s;//从源点开始搜寻。 
	for(int i = 0; i < n - 1; i++)
	{
		for(int j = 0; j < n; j++)
		{
			if(N[j].flag == 1)continue;//已访问,直接跳到下一个结点。 
			if(key[j] > (key[c1] + minpath(c1, j, e, m)))
				{
					key[j] = key[c1] + minpath(c1, j, e, m);
					pre[j] = c1;
				}
		}
		int min = 101, j = 0;;
		for(;j < n; j++)
		{
			if(N[j].flag == 1)continue;
			if(key[j] <= min)
				{
					min = key[j];
					c2 = j;
				}
		}
		
		N[c2].flag = 1;
		if(i == 0)pre[c2] = c1;
		p[c2].length = key[c2];
		c1 = c2;
	}

	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(p[j].length < p[i].length)
			{
				path pp = p[j];
				p[j] = p[i];
				p[i]= pp;
			}

	int count = 1, flag = 0;
	for(int i = 0; i < n; i++)
	{
		int num = p[i].k;
		if(p[i].k == s)continue;
		if(p[i].length == 101)
		{
			flag++;
			continue;
		}

		stack<int> st;
		st.push(num);
		while(pre[num] != s)
		{
			st.push(pre[num]);
			num = pre[num];
		}

		cout << "No." << count++ << " : " << s + 1 << " ";
		while(!st.empty())
		{
			cout << "-> " << st.top() + 1 << " ";
			st.pop();
		}
		cout << ", d = " << p[i].length << endl;
	}

	if(flag > 0)
	{
	cout << "No." << count << " : No Path to";
	int *np = new int[flag];
	int q = 0;
	for(int i = 0; i < n; i++)
	{
		if(p[i].length == 101) np[q++] = p[i].k + 1;
	}

	for(int i = 0;i < flag; i++)
		for(int j = i + 1; j < flag; j++)
			if(np[j] < np[i])
			{
				int tmp = np[j];
				np[j] = np[i];
				np[i] = tmp;
			}

	for(int i = 0; i < flag; i++)cout << " " << np[i];
	}

	return 0;

}

根据next数组推导模式字符串

题目描述
根据KMP算法的next数组值,推断模式字符串。

假设模式字符串中只存在0,1两种字符。给出首字符和next数组。请输出模式字符串。如果next数组不合法则输出ERROR

Input Format
先输入模式字符串首字符0或者1,然后输入尾字符0或者1

再输入 模式字符串长度n,n<=30

最后输入n个以 -1,0,起始的整数。

Output Format

模式字符串 或者 ERROR

Example
Input
1 0 10

-1 0 1 2 3 4 0 1 2 3

Output
1111101110

Input
1 1 6

-1 0 0 0 0 0

Output
100001

Input
1 1 6

-1 0 2 0 0 0

Output
ERROR

说明
以传统未优化的KMP算法推导的next数组。

#include <iostream>
using namespace std;

int kmp(int* next, int f, int l, int n) 
{
	int cur;
	int* tmp = new int[n];
	tmp[0] = f; 
	for (int i = 2; i < n; i++) 
	{
		if (next[i] == 0)//最大匹配长度为0 
		{
			if (f == 1) cur = 0;//当前字符的前一个字符与首字符相异 
			else cur = 1;
		}
		else 
		{
			if (next[i] >= i || ( i != next[i] + 1 && tmp[i - next[i] - 1] == tmp[0])) //错误:最大匹配长度过长或字符不匹配时不能回溯到正确位置  
			{
				cout << "ERROR" << endl;
				return 0;
			}
			cur = tmp[next[i] - 1];
		}
		tmp[i - 1] = cur;
	}
	for (int i = 0; i < n - 1; i++)
	{
		cout << tmp[i];
	}
    cout << l;
    cout << endl;
    return 0;
}
int main() 
{
	int f, l, n;
	cin >> f >> l >> n;
	int* next = new int[n];
	for (int i = 0; i < n; i++)
		cin >> next[i];
	kmp(next, f, l, n);
	return 0;
}

样例1
输入:
1 1 6
-1 0 0 0 0 0
输出:
100001
样例2
输入:
1 1 6
-1 0 2 0 0 0
输出:
ERROR
样例3
输入:
1 1 7
-1 0 1 2 3 4 2
输出:
ERROR

村庄是否联通

题目描述
村庄中存在一些路,根据输入的相邻村庄的路,判断某两个村庄是否能够联通。n个村庄使用0到n-1的不同整数标识。路使用取值范围【0,n-1】的整数对表示。例如 3 5,代表村庄3和5之间有一条路。

Input Format

村庄个数 n, 0<n<=20

路的条数 m,0<m<=50

m条路,即为2m个范围在【0,n-1】的整数

需要判断是否相连的村庄对数 p 0<p<=10

需要判断是否相连的p对村庄,即为2p个范围在【0,n-1】的整数。

Output Format
能够连通输出

true

不可连通输出

false

#include<iostream>
using namespace std;
class unionfind 
{
private:
	int* parent;
	int size;
public:
	unionfind(int s) 
	{
		size = s;
		parent = new int[size];
		for (int i = 0; i < size; i++) 
		{
			parent[i] = i;
		}
	}
	int find(int x) 
	{
		while (parent[x] != x)
			x = parent[x];
		return x;
	}
	void combine(int v1, int v2) 
	{
		int par1 = find(v1);
		int par2 = find(v2);
		if (par1 == par2)
			return;
		else 
		{
			if (par1 > par2)
				parent[par2] = par1;
			else if (par1 < par2)
				parent[par1] = par2;
			
			return;
		}
	}
	bool isconnect(int v1, int v2) 
	{
		return (find(v1) == find(v2));
	}
};
int main() {
	int n, m, p;
	int v1, v2;
	int result;
	cin >> n >> m;
	unionfind u(n);
	for (int i = 0; i < m; i++) 
	{
		cin >> v1 >> v2;
		u.combine(v1, v2);
	}
	cin >> p;
	int* num = new int[2 * p];
	for (int i = 0; i < 2*p;) 
	{
		cin >> num[i] >> num[i+1];
		i += 2;
	}
	for (int i = 0; i < 2 * p;) 
	{
		result = u.isconnect(num[i], num[i + 1]);
		if (result == 0)
			cout << "false" << endl;
		else
			cout << "true" << endl;
		i += 2;
	}
	return 0;
}

样例1
输入:
5
4
0 4
2 4
0 2
1 3
2
3 4
2 4
输出:
false
true

互斥字符串

题目描述
给定一个仅含有英文大小写字母的字符串序列 s,若其中任意两个相邻字符都不是同一个字母的大小写形式,则称其为互斥字符串。

程序需要将给定的字符串转换为互斥字符串。aa为互斥,aA和Aa为非互斥。

程序的每次操作可以从字符串中选出满足上述条件的两个相邻字符并删除,直到字符串整理好为止。

注:若最终结果为空字符串,请输出 -1。

要求时间复杂度O(n)

Input Format
输入由一行字符串组成。测试样例保证答案唯一。

Output Format
输出一行,为输入字符串经过若干次删除操作得到的互斥字符串。

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
	string s;
	cin>>s;
	stack<char>a;
	stack<char>b;
	a.push(s[0]);
	int i=1;
	while(s[i]!='\0')
	{
		if(a.empty())
		{
			a.push(s[i]);
		}
		else if ((a.top()==s[i]+32)||(a.top()==s[i]-32))
		{
			a.pop();
		}
		else
		{
			a.push(s[i]);
		}
		i++;
	}
	if (a.empty())
		cout<<-1;
	else
	{	while(!a.empty())
		{
			b.push(a.top());
			a.pop();

		} 
		while(!b.empty())
		{
			cout<<b.top();
			b.pop();
		}
	return 0;

	
	}
	
}

Example
Input
abBAcCc
Output
c
说明
该样例存在多种转换路径,但最终输出相同
“abBAcCc” --> “aAcCc” --> “cCc” --> “c”
“abBAcCc” --> “abBAc” --> “aAc” --> “c”
样例1
输入:
abBAcCc
输出:
c
样例2
输入:
AaBbCcDd
输出:
-1

工程最短消耗

题目描述
给出一个工程中N个阶段的时间消耗和依赖关系,试求出工程的最短时间消耗。

Input Format
输入N 0<N<=20。

随后输入N行数据,每行包含从1起始的阶段编号S、时间消耗T、以及用分号隔开的所依赖的不同阶段编号【如果不依赖其他阶段则此项为空】

Output Format

输出一行,为完成N个阶段的时间消耗。如果依赖关系不为DAG则输出"error"

样例1
输入:
4
1 3
2 4
3 5 1;2;
4 3 3;
输出:
12
样例2
输入:
4
1 3 3;
2 4
3 5 1;2;
4 3 3;
输出:
error

#include<iostream>
#include<string>
#include<queue>
using namespace std;

int loop(int a[20][20],int N)//判断依赖关系是否成立 
{
	queue<int> q;
	int* in = new int[N];
	int* visit = new int[N];
	for(int i = 0; i < N; i++) 
	{
		in[i] = 0;
		visit[i] = 0;
	}

	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < N; j++)
		{
			if(a[i][j] != -1)
				in[j]++;				
	    }
	}

	for(int i = 0; i < N; i++)
	{
		if(in[i] == 0)
		{
			q.push(i);
			visit[i] = 1;
			break;
		}		
	}

	while(!q.empty())
	{
		int t = q.front();
		for(int i = 0; i < N; i++)
		{
			if(a[t][i] != -1) in[i]--;
		}
		for(int i = 0; i < N; i++)
		{
			if(in[i] == 0 && visit[i] == 0)
			{
				q.push(i);
				visit[i] = 1;
		    }			
		}

		q.pop();
	}

	for(int i = 0; i < N; i++)
	{
		if(visit[i] == 0)return -1;
	}

	return 0;

}

int maxpath(int s, int a[20][20], int N, int* e)
{
	int* et = new int[N];
	int* flag = new int[N];
	for(int i = 0; i < N; i++)
		{
			et[i] = 0;
			flag[i] = 0;
		}

	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int t = q.front();
		for(int i = 0; i < N; i++)
			if(a[t][i] != -1)
			{
				q.push(i);
				et[i] = (et[i] > et[t] + a[t][i]) ? et[i] : et[t] + a[t][i];
				flag[t] = 1;//后面的时间已包括该阶段消耗时间; 
			}

		q.pop();
	}

	for(int i = 0; i < N; i++)
		et[i] += e[i];

	int max = 0;
	for(int i = 0; i < N; i++)
	{
		if(flag[i] == 0 && et[i] > max) 
		{
			max = et[i];
		}
    }
		

	return max;
}

int main()
{
	int N;
	string s;
	cin >> N;
	getchar();
	int a[20][20];
	int* e = new int[N];
	
	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < N; j++)
			a[i][j] = -1;		
	}


	for(int i = 0; i < N; i++)
	{
		getline(cin, s);//istream& getline ( istream &is , string &str , char delim );默认的char delim为'\n'; 
		int k = 2;
		if(s[k] == ' ') k++;

		if((k + 1 < s.length() && s[k + 1] == ' ') || k == s.length() - 1)
			{
				e[i] = s[k] - '0';//存入活动消耗的时间 
				k += 2;
				
			}
		else 
		{
			e[i] = 10 * (s[k] - '0') + s[k + 1] - '0';
			k += 3;
		}

		while(k + 1 < s.length())
		{
			if(s[k+1] == ';')
				{
					a[s[k] - '0' - 1][i] = s[k] - '0' - 1;
					k += 2;
				}
			else 
			{
				a[(s[k] - '0' - 1) * 10 + s[k + 1]- '0' - 1][i] = (s[k] - '0' -1 ) * 10 + s[k + 1] -'0' - 1;
				k += 3;
			}
		}
	}

	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < N; j++)
		{
			if(a[i][j] != -1) a[i][j] = e[a[i][j]];				
		}	
	}


	if(loop(a,N) == -1)
	{
		cout << "error" << endl;
		return 0;
	}
	else
	{
	    int max = 0;
		for(int i = 0; i < N; i++)
		{
			int flag = 0;
			for(int j = 0; j < N; j++)
			{
				if(a[j][i] != -1)
					{
						flag = 1;
						break;
					}				
			} 
			if(flag == 0)
				{
					int t = maxpath(i, a, N, e);
					if(t > max)max = t;
			    }
	    }

	cout << max << endl;
	
	return 0;
	}
}

DS-达式求值

题目描述
设计一个表达式求值的程序。该程序必须可以接受包含(,),+,-,*,/,%和^(求幂)的中缀表达式,并求出结果。如果表达式正确,则输出表达式的值,如果表达式非法,则输出错误信息。
注意223转为后缀应为223^^

操作数均转为double运算。

幂运算可以直接使用pow(a,b)

%,操作数转为Int再进行计算。

输入要求:
多个表达式,每个表达式占一行。

输出要求:
对每个表达式,如果为正确表达式则输出结果(精确到小数点后两位),如果为错误表达式则输出“ERROR IN INFIX NOTATION”

样例1
输入:
(2-4)^3
输出:
-8.00
样例2
输入:
(35(4+8)%2)
输出:
0.00
样例3
输入:
1+2(
输出:
ERROR IN INFIX NOTATION

#include <iostream>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
#include <iomanip>
using namespace std;
 
char s[1000];
int  g_pos;  // 字符数组的下标
 
/* 字符转数字 */
double Translation(int & pos)
{
    double integer = 0.00;    // 整数部分
    double remainder = 0.00;  // 小数部分
 
    while (s[pos] >= '0' && s[pos] <= '9')
    {
        integer *= 10;
        integer += (s[pos] - '0');
        pos++;
    }
 
    if (s[pos] == '.')
    {
        pos++;
        int c = 1;
        while (s[pos] >= '0' && s[pos] <= '9')
        {
            double t = s[pos] - '0';
            t *= pow(0.1, c);
            c++;
            remainder += t;
            pos++;
        }
    }
 
    return integer + remainder;
}
 
/* 返回运算符级别 */
int GetLevel(char ch)
{
    switch (ch)
    {
    case '+':
    case '-':
        return 1;
    case '*':
    case '/':
        return 2;
    case '^':
    case '%':
    	return 3;
    case '(':
        return 0;
    case '#':
        return -1;
    };
}
 
/* 对两个数进行运算 */
double Operate(double a1, char op, double a2)
{
	int a = a1;
    int b = a2;
    switch (op)
    {
    case '+':
        return a1 + a2;
    case '-':
        return a1 - a2;
    case '*':
        return a1 * a2;
    case '/':
        return a1 / a2;
    case '%':
    	return a % b;
    case '^':
    	return pow(a1,a2);
    };
}
 
/* 利用两个栈进行模拟计算 */
double Compute()
{
    stack<char> optr;    // 操作符栈
    stack<double> opnd;  // 操作数栈
 
	optr.push('#');      //置于符栈顶
    int len = strlen(s);
    bool is_minus = true;  // 判断是不是负号
 
    for (g_pos = 0; g_pos < len;)
    {
        //1. 负号
        if (s[g_pos] == '-' && is_minus)  // 是负号
        {
            opnd.push(0);
            optr.push('-');
            g_pos++;
        }
        //2. 是右括号 )
        else if (s[g_pos] == ')')
        {
            is_minus = false;
            g_pos++;
 
            while (optr.top() != '(' && optr.size() > 1)
            {
                double a2 = opnd.top();
                opnd.pop();
                double a1 = opnd.top();
                opnd.pop();
                char op = optr.top();
                optr.pop();
 
                double result = Operate(a1, op, a2);
                opnd.push(result);
            }
            optr.pop();  // 删除'('
            if (optr.size() < 1)
            {
            	cout << "ERROR IN INFIX NOTATION" << endl;
            	return 0;
			}
        }
        //3. 数字
        else if (s[g_pos] >= '0' && s[g_pos] <= '9')
        {
            is_minus = false;
            opnd.push(Translation(g_pos));
        }
        //4. ( 左括号
        else if (s[g_pos] == '(')
        {
            is_minus = true;
            optr.push(s[g_pos]);
            g_pos++;
        }
        //5. + - * / ^ % 
        else if (s[g_pos] == '+' || s[g_pos] == '-' || s[g_pos] == '*' || s[g_pos] == '/' || s[g_pos] == '^' || s[g_pos] == '%' )
        {
            while (GetLevel(s[g_pos]) <= GetLevel(optr.top()))    //当前优先级小于栈顶优先级
            {
                double a2 = opnd.top();
                opnd.pop();
                double a1 = opnd.top();
                opnd.pop();
                char op = optr.top();
                optr.pop();
 
                double result = Operate(a1, op, a2);
                opnd.push(result);
            }
 
            optr.push(s[g_pos]);
            g_pos++;
        }
        //6.输入字符不属于数字或规定运算符 
        else
        {
        	cout << "ERROR IN INFIX NOTATION" << endl;
        	return 0;
		}
    }
    
    //对剩余的运算符及操作数进行计算 
    while (optr.top() != '#' && opnd.size() >= 2)
    {
        double a2 = opnd.top();
        opnd.pop();
        double a1 = opnd.top();
	    opnd.pop();
	    char op = optr.top();
	    double result = Operate(a1, op, a2);
        opnd.push(result);
        optr.pop();
    }
    optr.pop();
    //计算结束并弹出#后运算符栈仍不为空,说明最后弹出的不为#,有多余运算符 
	if (!optr.empty())
    {
    	cout << "ERROR IN INFIX NOTATION" << endl;
    	return 0;
	}
	else if(opnd.size() != 1)
    {
    	cout << "ERROR IN INFIX NOTATION" << endl;
    	return 0;
	}
	else
	{
	    cout << setiosflags(ios::fixed) << setprecision(2) << opnd.top() << endl;
	    return 0;
	}
	

}
 
int main()
{
    cin >> s;
    Compute();
    return 0;
}

最低能量消耗

题目描述
自然界有一种物质,同种两个物质结合需要消耗的能量为两个物质的质量和。假设只能两两结合,根据输入的该类物质碎片质量,求全部碎片结合成一个整体,需要的最小能量。

Input Format

碎片总个数0<n<=50

n个碎片的质量【取值范围(0,10000)的n个整数】

Output Format
两两结合需要的最小能量

Example
Input
5
1 4 5 2 6
Output
39
样例1
输入:
5
1 4 5 2 6
输出:
39
样例2
输入:
2
7 8
输出:
15

多源最短路径

在这里插入图片描述

样例1
输入:
3 5
0 1 6
0 2 13
1 0 10
1 2 4
2 0 5
输出:
0 6 10
9 0 4
5 11 0
样例2
输入:
6 0
输出:
0 -1 -1 -1 -1 -1
-1 0 -1 -1 -1 -1
-1 -1 0 -1 -1 -1
-1 -1 -1 0 -1 -1
-1 -1 -1 -1 0 -1
-1 -1 -1 -1 -1 0

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构题目汇总 的相关文章

随机推荐

  • 将matlab变量导入excel并生成行列标题

    1 将matlab里生成的变量导入到excel中 xlswrite 具体路径 data xlsx AG set 1 B1 k1 xlswrite 表格路径 变量名称 sheet1 数据显示的范围 2 为生成的表格指定行列标题 xlswrit
  • React的事件处理

    目录 一 React的事件处理 1 与DOM事件处理的不同之处 1 React事件的命名方式 小驼峰方式 DOM的命名方式是小写 2 事件处理函数是以对象的方式赋值 而不是以字符串的方式赋值 3 阻止默认事件的方式不同 2 React中事件
  • /PROC/MEMINFO之谜

    proc meminfo是了解Linux系统内存使用状况的主要接口 我们最常用的 free vmstat 等命令就是通过它获取数据的 proc meminfo所包含的信息比 free 等命令要丰富得多 然而真正理解它并不容易 比如我们知道
  • Rust- 结构体

    In Rust a struct short for structure is a custom data type that lets you name and package together multiple related valu
  • 2.5 SPPNet

    目录 2 5 SPPNet 2 5 1 SPP 的目的 2 5 2 SPP 架构 2 5 3 SPP 用于目标检测 2 5 4 候选区域映射 参考资料 2 5 SPPNet SPP Spatial Pyramid Pooling 空间金字塔
  • cpu调优

    1 大内存页 2 数据刷写频率 忍受多长时间丢失 越长越好 脏数据有可能把内存耗尽的危险 3 尽可能不把内存数据放到swap中 当物理内存使用到了6成有可能就开始使用swap了 跑tomcat hadoop python java 内程序尽
  • 《与韩荆州书》--李白经典求职信

    白闻天下谈士相聚而言曰 生不用封万户侯 但愿一识韩荆州 何令人之景慕 一至于此耶 岂不以有周公之风 躬吐握之事 使海内豪俊奔走而归之 一登龙门 则声誉十倍 所以龙盘凤逸之士 皆欲收名定价于君侯 愿君侯不以富贵而骄之 寒贱而忽之 则三千宾中有
  • 图解Windows10下如何更换Jupyter Notebook 内核Python版本(切换原始的python环境)

    问题描述 启动Jupyter Notebook之后它会自动加载原始的python环境 如下图所示 但是自己又在Anaconda中下载了新的虚拟环境 很多库都在这个虚拟环境中 那么如何让Jupyter Notebook加载自己的这个虚拟环境呢
  • python练习.一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

    high tour hei 100 for i in range 0 10 if i 0 tour append hei else tour append 2 hei hei 2 high append hei print 总高度 tour
  • redis单机,集群搭建教程

    环境准备 Linux 版本 Centos 7 0 2009 Redis版本 redis 5 0 3 tar gz 文章目录 一 redis是什么 二 单机搭建步骤 三 集群搭建步骤 在一台机子搭建一个伪集群 总结 一 redis是什么 通常
  • LaTex 加粗(加黑)的方式

    1 基本 LaTeX技巧458 关于LaTeX数学字体加粗 mathbf 会变为粗体 但也导致数学字母斜体形式的丢失 使用 amsmath package 的 boldmath 命令 boldmath f x y 3 x y y 2xy 7
  • Failed to initialize NVML: Driver/library version mismatch

    nvidia驱动安装之后 nvidia smi 报错 Driver library version mismatch 不重启系统的解决方法 查看系统日志 确定具体报错信息 dmesg tail 8598493 408944 NVRM API
  • Unity2018新功能抢鲜

    本文首发于 洪流学堂 微信公众号 洪流学堂 让你学Unity快人几步 洪流学堂公众号回复节点 获取ShaderGraph节点详解PDF文件 带目录 Shader一直是Unity开发者的一个难关 涉及到数学 图形学 shader语法等多个难题
  • oracle 导出指定表和导入

    导出之前要注意一个问题 版本的问题 所以导出的语句应该指定版本 版本应该是要导入这些表的数据库的版本 expdp user password sid tables table1 table2 file expdp2022111 dmp ve
  • LeetCode力扣热题一百·自我解法记录(JAVA版本·仅代码)

    1 两数之和 哈希表 题目链接 力扣 两数之和 简单 import java util HashMap class Solution public int twoSum int nums int target 创建哈希表 HashMap
  • JavaScript - 插入排序的两种方式

    插入排序1 新建一个新数组 循环遍历原始数据 把原始数组内的每一个逐个插入到新数组内 在插入的时候 按照一定的顺序插入 原始数组 var arr 9 2 5 3 7 6 4 1 8 准备一个新数组 var newarr 循环遍历原始数组 f
  • 大学生团体天梯赛(第六届)

    题目地址 天梯赛 include
  • 高级信息系统项目管理师十大领域

    文章目录 一 项目整合管理 1 制定项目章程 2 制定项目管理计划 3 指导与管理项目工作 4 管理项目知识 5 监控项目工作 6 实施整体变更控制 7 结束项目或阶段 二 项目范围管理 1 规划范围管理 2 收集需求 3 定义范围 项目范
  • Flutter 常用插件

    dio http请求库 flutter swiper carousel slider 图片 轮播组件库 package info url launcher 系统库 app相关信息 打电话 发邮件等 pull to refresh flutt
  • 数据结构题目汇总

    求整数最大间隔 性能 hash算法应用 题目描述 请输出数字序列的最大间隔 请使用以下伪随机数生成函数 rand32 生成伪随机数 int seed int rand return seed seed 214013L 2531011L gt