大二上数据结构1-3章作业个人作法

第一章

1-1.最大因子 

【问题描述】

     给定一组共n(1≤n≤5000)个整数,整数的取值范围为1到20000,请确定具有最大素数因子的整数(请记住,素数只有因子1和自身,整数7是素数,而整数6可以被2和3整除,它不是素数)。

【输入形式】

      第一行为单个整数n,接下来共n个整数,每行包含一个整数。

【输出形式】

      在一行中输出具有最大素数因子的那个整数,如果有多个,则输出最早出现在输入文件中的一个。

【样例输入】

   4

  36

  38

  40

  42

【样例输出】

  38
【样例说明】

  测试数据的文件名为in.txt

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

int main() {
	ifstream input;
	input.open("in.txt");
	int n;
	int num;
	int max = 0;
	int ans = 0;

	string str;
	getline(input, str);
	n = stoi(str);                            //获取数字个数

	while (n > 0) {                           //读取数据
		getline(input, str);
		num = stoi(str);

		int k = 2;
		int numcpy = num;

		if (num == 1) {
			k = 1;
		}

		while (num > 1) {                     //求数据的最大素因子
			if (num % k == 0) {
				num = num / k;
			} else {
				k++;
			}

		}
		if (k > max) {                        //如果大于最大值,答案为此数字
			max = k;
			ans = numcpy;
		}
		n--;
	}

	cout << ans;
	return 0;
}

1-2.回文数

【问题描述】

判断一个整数是否是回文数。例如,121是回文数,而-121不是回文数。


【输入形式】

      每个测试用例输入一行,是一个整数。

【输出形式】

     对于每个测试用例输出一行,输出0表示不是回文数,或者输出1表示是回文数。

【样例输入】

     12345
【样例输出】

     0
【样例说明】

   测试用例中的每一行代表一个待测试的整数,测试数据的文件名为in.txt。

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

int main() {
	ifstream input;
	input.open("in.txt");

	string str;
	getline(input, str);
	int n = stoi(str);
	int ncpy = n;
	int b = -1;
	int i = 0;

	if (n < 0) {
		cout << 0;
		return 0;
	}
	while (ncpy != 0) {                            //算出n的位数,赋值于b
		ncpy = ncpy / 10;
		b++;
	}
	while (i < b) {
		int high = n;
		int low = n;
		for (int bcpy = b; bcpy > 0; bcpy--) {     //求高位数字
			high = high / 10;
		}
		for (int icpy = i; icpy > 0; icpy--) {     //求低位数字    
			low = low / 10;
		}
		if (high % 10 != low % 10) {               //判断是否相等
			cout << 0;
			return 0;
		}
		i++;
		b--;
	}
	cout << 1;
	return 0;
}

第二章 

2-1.集合并集运算

【问题描述】

给你两个集合A和B,要求{A}+{B}。注意同一个集合中不会有两个相同的元素。

【输入形式】

      每组输入数据分为三行,第一行有两个数字n,m(0<n,m≤10000),分别表示集合A和集合B的元素个数。后两行分别表示集合A和集合B,每个元素为不超出int范围的整数,两个元素之间有一个空格隔开。

【输出形式】

      针对每组数据输出一行数据,表示合并后的集合,要求从小到大输出,两个元素之间有一个空格隔开。

【样例输入】

1 2

1

2 3

【样例输出】

       1 2 3
【样例说明】

      第一行的两个数字表示集合A和集合B的元素个数,后面两行分别表示集合A和集合B中的整数元素,两个元素之间用空格隔开。测试数据存放在in.txt文件中。

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <set>
using namespace std;

int main() {
	ifstream input;
	input.open("in.txt");

	set<int> s;                                        //集合并集,直接使用集合
	string line;
	string data;
	getline(input, line);
	while (getline(input, line)) {
		istringstream iss(line);
		while (iss >> data) {                          //分行输入,不存在则添加
			if (s.find(stoi(data)) == s.end()) {
				s.insert(stoi(data));
			}
		}
	}

	for (set<int>::iterator it = s.begin(); it != s.end(); it++) {    //遍历输出
		cout << *it << " ";
	}
	return 0;
}

2-2.重排链表

【问题描述】

    假设不带头结点的单链表结点类型如下:

struct ListNode
{ int val;
 ListNode *next;
 ListNode(int x):val(x),next(NULL){}
};

给定一个含n+1个结点的单链表L:L0→L1→…→Ln-1→Ln,将其重新排列后变为:L0→Ln→L1→Ln-1→L2→Ln-2→…。你不能只是单纯的改变结点内部的值,而是需要实际的进行结点交换。示例1,给定链表为1->2->3->4,重新排列为1->4->2->3。示例2,给定链表为1->2->3->4->5,重新排列为1->5->2->4->3。你需要设计的reorderList函数。

【输入形式】

    输入含有n个元素的单链表。

【输出形式】

    输出重排后的单链表中的元素。

【样例输入】

    1 2 3 4

【样例输出】

    1 4 2 3

【样例说明】

    输入文件名为in.txt。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

struct ListNode
{
    int val;
    ListNode *next;
    ListNode() : val(0), next(NULL) {}
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution
{
public:
    ListNode *reorderList(ListNode *head)                    //重排链表
    {
        vector<int> vec;
        vector<int> vec2;
        ListNode *headcpy = head;
        while (head != NULL)                                //根据传入链表构建数组
        {
            vec.push_back(head->val);
            head = head->next;
        }
        delete headcpy;
        for (int i = 0, j = vec.size() - 1; i <= j; i++, j--)    //重排数组
        {
            vec2.push_back(vec[i]);
            vec2.push_back(vec[j]);
            if (i == j)
            {
                vec2.pop_back();
            }
        }
        return buildList(vec2);                            //根据重排后数组再次构建链表
    }

    ListNode *buildList(vector<int> vec)              //传入数组,构建链表,返回链表头结点
    {
        ListNode *pre = NULL;
        for (vector<int>::reverse_iterator rit = vec.rbegin(); rit != vec.rend(); rit++)
        {
            ListNode *node = new ListNode();
            node->val = *rit;
            node->next = pre;
            pre = node;
        }
        return pre;
    }
};

int main()
{
    Solution solution = Solution();

    ifstream input;
    input.open("in.txt");
    string data;
    vector<int> vec;
    while (input >> data)
    {
        vec.push_back(stoi(data));
    }

    ListNode*pre=solution.buildList(vec);
    pre = solution.reorderList(pre);
    while (pre != NULL)                            //遍历链表
    {
        cout << pre->val << " ";
        pre = pre->next;
    }
    return 0;
}

第三章

3-1.晒黑沙龙

【问题描述】

有一个Tan Your Hide的公司拥有数家投币式晒黑沙龙。研究表明,如果客户到达而没有可用的床位,则客户可能会转身离开,从而使公司损失一笔销售费用。你的任务是编写一个程序告诉公司有多少客户不晒黑就离开了。

【输入形式】

输入内容包含一个沙龙数据,该沙龙的数据是一行,其中包含一个正整数,代表沙龙中的日光浴床数量,后跟一个空格,然后是一个大写字母序列,序列中的字母是成对出现的,第一次出现表示该客户的到来,第二次出现表示同一客户的离开,不会出现超过一对的字母。没有晒黑就离开的客户总是先于当前晒黑的客户离开。每个沙龙最多可容纳20张床。

【输出形式】

对于每个沙龙,输出一个句子,告诉有多少顾客走了,使用样例显示的确切格式。比如,若有2个顾客走了,则输出2 customer(s) walked away. 若没有顾客离开,则输出All customers tanned successfully.

【样例输入】

1 ABCBCA

【样例输出】

2 customer(s) walked away.

【样例说明】

      2代表沙龙中有两张床,ABC等字母代表单个人,第1次出现代表入住,第2次出现代表离开。上述样例的处理过程如下:

① A入住

② B入住,入住失败

③ C入住,入住失败

④ B离开,共1人离开(未住店)

⑤ C离开,共2人离开(未住店)

⑥ A离开

结果是“2 customer(s) walked away.”。

测试数据存放在in.txt文件中。

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

int main() {
	ifstream input;
	input.open("in.txt");

	set<char> s;          //使用中顾客集合
	set<char> waits;      //等待中顾客集合
	queue<char> wait;     //排队等待队列
	int count = 0;        //没晒黑就离开的顾客数量

	string line;
	int num;
	char data;
	input >> num;         //读取浴床数量
	while (input >> data) {                   //读取顾客
		if (s.find(data) != s.end()) {        //如果顾客在使用,则顾客离开
			s.erase(data);                    //等待队列首位如果仍在等待集合中,则使用
			while (!wait.empty() && waits.find(wait.front()) == waits.end()) {
				wait.pop();                   //否则不断弹出
			}
			if (!wait.empty()) {              //找到未离开的队列首位,进入使用,并出队
				waits.erase(wait.front());
				s.insert(wait.front());
				wait.pop();
			}

		} else {                              //如果顾客在等待,则顾客离开,离开人数加一
			if (waits.find(data) != waits.end()) {
				count++;
				waits.erase(data);            //从等待集合中删除
			} else {
				if (s.size() >= num) {        //如果使用人数已满,加入等待集合和队列中
					waits.insert(data);
					wait.push(data);
				} else {                      //未满则直接使用
					s.insert(data);
				}
			}
		}
	}
	if (count > 0) {                          //输出未晒黑就离开人数
		cout << count << " customer(s) walked away." << endl;
	} else {
		cout << "All customers tanned successfully." << endl;
	}

	return 0;
}

3-2.两数之和

【问题描述】

  给定一个整数数组nums和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。例如,给定nums=[2,7,11,15],target=9,返回结果为[0,1]。若没有答案,则返回[-1,-1]。

【输入形式】

     每个测试用例由两行数据构成,第一行给出整数数组,元素之间以空格隔开,可以有重复元素;第二行给出求和的目标值。

【输出形式】

     返回累加和为目标值的两个整数在数组中的下标值,不限顺序。若没有答案,则返回[-1,-1]。

【样例输入】

    2 7 11 15

    9

【样例输出】

    0 1

【样例说明】

    输入的整数数组有四个整数,分别为2,7,11,15,目标值为9。数组中的2和7的累加和为9,因此返回这两个整数在数组中的下标地址,即0,1。测试数据文件名为in.txt。

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
using namespace std;

class Solution {
	public:
		vector<int> twoSum(vector<int> vec, int target) {
			vector<int> ans;            //答案数组
			unordered_map<int, int> map;
			for (int i = 0; i < vec.size(); i++) {        
				if (map.find(target - vec[i]) != map.end()) {    //查找map
					ans.push_back(map[target - vec[i]]);    //存在则数组加入两数下标
					ans.push_back(i);
					return ans;
				}
				map.insert(pair<int, int>(vec[i], i));    //数组元素按<数值,下标>入map
			}
			ans.push_back(-1);                            //否则输出[-1,-1]
			ans.push_back(-1);
			return ans;
		}
};

int main() {
	Solution solution = Solution();
	ifstream input;
	input.open("in.txt");

	vector<int> vec;
	string line;
	string data;
	getline(input, line);
	istringstream iss(line);

	while (iss >> data) {                    //根据输入构建数组
		vec.push_back(stoi(data));
	}
	getline(input, line);

	int target = stoi(line);                //获取目标值
	vector<int> ans = solution.twoSum(vec,target);
	for (vector<int>::iterator it = ans.begin(); it != ans.end(); it++) {
		cout << *it << " ";
	}

}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值