算法笔记Codeup、pat刷题记录(含个人笔记)第六章

2021算法笔记Codeup、pat刷题记录

《算法笔记》6.1小节——C++标准模板库(STL)介绍->vector的常见用法详解

Course List for Student (25)

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int N = 26 * 26 * 26 * 10 + 1;//hash表的上界
vector<int> studentinfo[N];

int getID(char name[]) {//使用字符串哈希,将学生名与数字一一对应
	int id = 0;
	for (int i = 0;i < 3;++i) {
		id = id * 26 + name[i] - 'A';
	}
	id = id * 10 + name[3] - '0';
	return id;
}

int main() {
	int n, k;
	char name[5];
	scanf("%d %d", &n, &k);
	for (int i = 0;i < k;++i) {
		int course, x;
		scanf("%d %d", &course, &x);
		for (int j = 0;j < x;++j) {
			scanf("%s", name);
			int id = getID(name);
			studentinfo[id].push_back(course);
		}
	}
	for (int i = 0;i < n;++i) {
		scanf("%s", name);
		int id = getID(name);
		printf("%s %d", name, studentinfo[id].size());
		sort(studentinfo[id].begin(), studentinfo[id].end());
		for (int j = 0;j < studentinfo[id].size();++j) {
			printf(" %d", studentinfo[id][j]);
		}
		printf("\n");
	}
	return 0;
}

Student List for Course (25)

用string写的,Codeup能过,PTA最后一个测试点会超时

#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

const int maxK = 2510;

vector<string> studentList[maxK];
int main() {
	int n, k;
	scanf("%d %d", &n, &k);
	for (int i = 0;i < n;++i) {
		int m;
		string name;
		cin >> name >> m;
		while (m--) {
			int temp;
			scanf("%d", &temp);
			studentList[temp].push_back(name);
		}
	}
	for (int i = 1;i <= k;++i) {
		printf("%d %d\n", i, studentList[i].size());
		sort(studentList[i].begin(), studentList[i].end());
		for (int j = 0;j < studentList[i].size();++j) {
			cout << studentList[i][j] << endl;
		}
	}
	return 0;
}

使用printf输出最后一个测试点的时间达到417 ms,这是晴神笔记上的代码思路,用char name[maxn][5]数组存放学生姓名,并且cmp函数中使用姓名对vector中的数字进行排序,这种想法很精妙。

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 40010;
const int maxk = 2510;
char name[maxn][5];
vector<int> course[maxk];

bool cmp(int a, int b) {//排序改变vector中的数字顺序,而不用改变数组中字符串的顺序,太妙了 
	return strcmp(name[a], name[b]) < 0;
}

int main() {
	int n, k;
	scanf("%d %d", &n, &k);
	for (int i = 0;i < n;++i) {
		int m;
		scanf("%s %d", name[i], &m);
		for (int j = 0;j < m;++j) {
			int temp;
			scanf("%d", &temp);
			course[temp].push_back(i);
		}
	}
	for (int i = 1;i <= k;++i) {
		printf("%d %d\n", i, course[i].size());
		sort(course[i].begin(), course[i].end(), cmp);
		for (int j = 0;j < course[i].size();++j) {
			printf("%s\n", name[course[i][j]]);//name[course[i][j]]易错 
		}
	}

	return 0;
}

《算法笔记》6.2小节——C++标准模板库(STL)介绍->set的常见用法详解

Set Similarity (25)

set是内部自动升序,且无重复元素的容器。

#include<cstdio>
#include<set>
using namespace std;
set<int> st[55];

void compare(int a, int b) {
	int sameNum = 0, allNum = st[b].size();//注意这里的初始值
	for (set<int>::iterator it = st[a].begin();it != st[a].end();++it) {
		if (st[b].find(*it) != st[b].end()) ++sameNum;
		else ++allNum;
	}
	printf("%.1f%%\n", 100.0 * sameNum / allNum);
}

int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1;i <= n;++i) {
		int m;
		scanf("%d", &m);
		while (m--) {
			int t;
			scanf("%d", &t);
			st[i].insert(t);
		}
	}
	int k;
	scanf("%d", &k);
	while (k--) {
		int a, b;
		scanf("%d %d", &a, &b);
		compare(a, b);
	}
	return 0;
}

《算法笔记》6.3小节——C++标准模板库(STL)介绍->string的常见用法详解

Codeup

字符串处理

额,相信了网上的正确答案,结果写完发现人家的也不能AC。。。自己这个问题也有点大,测试了一下如果小数部分算出来最大位是0的话,0是会输出不了的例如1563.123+18564.22,总是就是错了。问题很多

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

long long to_num(string s, int& e) {
	int flag = 1, bflag = 1, len = s.length(), f = 0;
	long long num = 0;
	for (int i = 0;i < len;++i) {
		if (s[i] == '-') flag = -1;//碰到负号将flag变为-1; 
		else if (s[i] == '.') f = 1;//s是浮点数;
		else if (s[i] == 'e' || s[i] == 'E') {//碰到e,E后面的指数 
			++i;
			if (s[i] == '-') {//指数是负的情况 
				bflag = -1;
				++i;
			}
			int temp = 0;
			while (i < s.length()) {
				temp = 10 * temp + s[i] - '0';
				++i;
			}
			e += temp * bflag;//指数加上E后指数 
		}
		else {
			num = 10 * num + s[i] - '0';
			e -= f;//如果有.则每次遍历需要使指数-1 
		}
	}
	num *= flag;
	return num;
}
int main() {
	string a, b;
	while (cin >> a >> b) {
		int e1 = 0, e2 = 0;
		long long numa = to_num(a, e1), numb = to_num(b, e2);
		if (e1 < e2) {
			while (e1 < e2) {
				numb *= 10;
				--e2;
			}
		}
		else {
			while (e1 > e2) {
				numa *= 10;
				--e1;
			}
		}
		//		printf("%lld %d %lld %d\n",numa,e1,numb,e2);
		long long num = numa + numb;
		int e = e1, d = 1, m = 0;
		for (long long i = num;i > 10;i /= 10) {
			d *= 10;
			++m;
		}
		//		printf("%d %d\n",d,m);
		printf("%lld", num / d);
		printf(".%lld", num % d);
		printf("e%d\n", e1 + m);
	}
	return 0;
}

配套实战指南

PAT A1060 Are They Equal

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

int n;

string change(string s, int& e) {
	int k = 0;
	while (s.length() > 0 && s[0] == '0') {
		s.erase(s.begin());
	}
	if (s[0] == '.') {
		s.erase(s.begin());
		while (s.length() > 0 && s[0] == '0') {
			s.erase(s.begin());
			--e;
		}
	}
	else {
		while (s[k] != '.' && k < s.length()) {
			++e;
			++k;
		}
		if (k < s.length()) s.erase(s.begin() + k);
	}
	if (s.length() == 0) e = 0;
	string res;
	int num = 0;
	k = 0;
	while (num < n) {
		if (k < s.length()) res += s[k++];
		else res += '0';
		++num;
	}
	return res;
}

int main() {
	string str1, str2;
	cin >> n >> str1 >> str2;
	int e1 = 0, e2 = 0;
	str1 = change(str1, e1);
	str2 = change(str2, e2);
	if (str1 == str2 && e1 == e2) cout << "YES 0." << str1 << "*10^" << e1 << endl;
	else cout << "NO 0." << str1 << "*10^" << e1 << " 0." << str2 << "*10^" << e2 << endl;
	return 0;
}

PAT A1100 Mars Numbers/

#include<cstdio>
#include<iostream>
#include<map>
#include<string>
using namespace std;

string unitDigit[13] = { "tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec" };
string tenDigit[13] = { "tret","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou" };
string numToStr[170];
map<string, int> strToNum;

void init() {
	for (int i = 0;i < 13;++i) {//对十位为0和百位为零的数赋值 
		numToStr[i] = unitDigit[i];
		strToNum[unitDigit[i]] = i;
		numToStr[13 * i] = tenDigit[i];
		strToNum[tenDigit[i]] = 13 * i;
	}
	for (int i = 1;i < 13;++i) {//对普通数赋值 
		for (int j = 1;j < 13;++j) {
			string temps = tenDigit[i] + " " + unitDigit[j];
			numToStr[13 * i + j] = temps;
			strToNum[temps] = 13 * i + j;
		}
	}
}

int main() {
	init();
	int n;
	scanf("%d", &n);
	getchar();//吸收回车键
	while (n--) {
		string str;
		getline(cin, str);
		int num = 0;
		if (str[0] >= '0' && str[0] <= '9') {
			for (int i = 0;i < str.size();++i) {
				num = num * 10 + str[i] - '0';
			}
			cout << numToStr[num] << endl;
		}
		else {
			cout << strToNum[str] << endl;
		}
	}
	return 0;
}

PAT A1054 The Dominant Color

map写法

#include<cstdio>
#include<map>
using namespace std;

int main() {
	int m, n;
	scanf("%d %d", &m, &n);
	n = m * n;
	map<int, int> count;
	for (int i = 0;i < n;++i) {
		int color;
		scanf("%d", &color);
		if (count.find(color) != count.end()) ++count[color];
		else count[color] = 1;
	}
	int k = 0, max = -1;
	for (map<int, int>::iterator it = count.begin();it != count.end();++it) {
		if (it->second > max) {
			k = it->first;
			max = it->second;
		}
	}
	printf("%d\n", k);
	return 0;
}

笔试题写法

#include<cstdio>

int main() {
	int m, n, ans, cnt = 0;
	scanf("%d %d", &m, &n);
	n = m * n;
	for (int i = 0;i < n;++i) {
		int color;
		scanf("%d", &color);
		if (color != ans) {//超过半数的数一定会留下
			if (cnt == 0) {
				ans = color;
				cnt = 1;
			}
			else --cnt;
		}
		else ++cnt;
	}
	printf("%d\n", ans);
	return 0;
}

PAT A1071 Speech Patterns

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

bool valid(char c) {
	if (c >= '0' && c <= '9') return true;
	else if (c >= 'A' && c <= 'Z') return true;
	else if (c >= 'a' && c <= 'z') return true;
	return false;
}

int main() {
	string sen, word;
	getline(cin, sen);
	map<string, int> count;
	for (int i = 0;i < sen.size();) {
		while (i < sen.length() && valid(sen[i])) {
			if (sen[i] >= 'A' && sen[i] <= 'Z') sen[i] += 32;
			word += sen[i];
			++i;
		}
		if (word.length() > 0) {
			if (count.find(word) == count.end()) count[word] = 1;
			else ++count[word];
			word.clear();
		}
		while (i < sen.length() && valid(sen[i]) == false) ++i;
	}
	string ans;
	int max = 0;
	for (map<string, int>::iterator it = count.begin();it != count.end();++it) {
		if (it->second > max) {
			ans = it->first;
			max = it->second;
		}
	}
	cout << ans << " " << max << endl;
	return 0;
}

PAT A1022 Digital Library

#include<cstdio>
#include<string>
#include<iostream>
#include<map>
#include<set>
using namespace std;

map<string, set<int> > mpTitle, mpAuthor, mpKey, mpPub, mpYear;

void query(map<string, set<int> >& mp, string& str) {
	if (mp.find(str) == mp.end()) printf("Not Found\n");
	else {
		for (set<int>::iterator it = mp[str].begin();it != mp[str].end();++it) {
			printf("%07d\n", *it);
		}
	}
}
int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		int IDnum;
		scanf("%d", &IDnum);
		getchar();
		string title, author, key, pub, year;
		getline(cin, title);
		mpTitle[title].insert(IDnum);
		getline(cin, author);
		mpAuthor[author].insert(IDnum);
		while (cin >> key) {
			mpKey[key].insert(IDnum);
			char c = getchar();
			if (c == '\n') break;
		}
		getline(cin, pub);
		mpPub[pub].insert(IDnum);
		getline(cin, year);
		mpYear[year].insert(IDnum);
	}
	scanf("%d", &n);
	getchar();
	for (int i = 0;i < n;++i) {
		string str, head;
		getline(cin, str);
		int m = str[0] - '0';
		cout << str << endl;
		str.erase(0, 3);
		switch (m) {
		case 1: {
			query(mpTitle, str);
			break;
		}
		case 2: {
			query(mpAuthor, str);
			break;
		}
		case 3: {
			query(mpKey, str);
			break;
		}
		case 4: {
			query(mpPub, str);
			break;
		}
		case 5: {
			query(mpYear, str);
			break;
		}
		}

	}
	return 0;
}

《算法笔记》6.5小节——C++标准模板库(STL)介绍->queue的常见用法详解

C语言-数字交换

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

void scan(vector<int> &vi){
	int n;
	for(int i=0;i<10;++i){
		scanf("%d",&n);
		vi.push_back(n);
	}
}

void change(vector<int> &vi){
	int min=100000,max=-1,minn=0,maxn=0;
	for(int i=0;i<10;++i){
		if(min>vi[i]){
			min=vi[i];
			minn=i;
		}
	}
	swap(vi[minn],vi[0]);
	for(int i=0;i<10;++i){
		if(max<vi[i]){
			max=vi[i];
			maxn=i;
		}
	}
	swap(vi[maxn],vi[9]);
}

void print(vector<int> vi){
	for(int i=0;i<10;++i) printf("%d ",vi[i]);
}

int main(){
	vector<int> vi;
	scan(vi);
	change(vi);
	print(vi);
	return 0;
}

《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解

简单计算器

#include<iostream>
#include<cstdio>
#include<string>
#include<map>
#include<stack>
#include<queue>
using namespace std;

struct node {
	double num;//操作数 
	char op;//操作符 
	bool flag;//ture 表示操作数,false表示操作符 
};

string str;
stack<node> s;
queue<node> q;
map<char, int> mp;

void change() {//将中缀表达式转换成后缀
	node temp;
	for (int i = 0;i < str.length();) {
		if (str[i] >= '0' && str[i] <= '9') {
			temp.flag = true;
			temp.num = str[i++] - '0';
			while (i < str.length() && str[i] >= '0' && str[i] <= '9') {
				temp.num = 10 * temp.num + str[i] - '0';
				++i;
			}
			q.push(temp);
		}
		else {
			temp.flag = false;
			while (!s.empty() && mp[str[i]] <= mp[s.top().op]) {
				q.push(s.top());
				s.pop();
			}
			temp.op = str[i];
			s.push(temp);
			++i;
		}
	}
	while (!s.empty()) {
		q.push(s.top());
		s.pop();
	}
}

double calculate() {
	node cur;
	while (!q.empty()) {
		cur = q.front();
		q.pop();
		if (cur.flag == true) s.push(cur);//如果是数,则压入栈中 
		else {//为操作符则拿出前两个数进行计算 
			node temp;
			temp.flag = true;
			double temp1, temp2;
			temp2 = s.top().num;
			s.pop();
			temp1 = s.top().num;
			s.pop();
			if (cur.op == '+') temp.num = temp1 + temp2;
			else if (cur.op == '-') temp.num = temp1 - temp2;
			else if (cur.op == '*') temp.num = temp1 * temp2;
			else temp.num = temp1 / temp2;
			s.push(temp);
		}
	}
	return s.top().num;
}

int main() {
	mp['+'] = mp['-'] = 1;
	mp['*'] = mp['/'] = 2;
	while (getline(cin, str), str != "0") {
		for (string::iterator it = str.begin();it != str.end();++it) {
			if (*it == ' ') str.erase(it);
		}
		while (!s.empty()) s.pop();//这里不写的话会导致后续结果出错 
		change();
		//	while(!q.empty()){//中间段的测试代码 
		//		if(q.front().flag==1) printf("%f",q.front().num);
		//		else printf("%c",q.front().op);
		//		q.pop();
		//	}
		printf("%.2f\n", calculate());
	}
	return 0;
}

Problem E

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

int main(){
	int n;
	scanf("%d",&n);
	getchar();
		while(n--){
			string str;
			getline(cin,str);
			stack<char> st;
			bool flag;
			for(int i=0;i<str.length();++i){
				flag=true;
				if(str[i]=='('||str[i]=='['||str[i]=='{') st.push(str[i]);
				else if(str[i]==')'){
					if(!st.empty()&&st.top()=='(') st.pop();
					else{
						flag=false;
						break;
					}
				}else if(str[i]==']'){
					if(!st.empty()&&st.top()=='[') st.pop();
					else{
						flag=false;
						break;
					}
				}else if(str[i]=='}'){
					if(!st.empty()&&st.top()=='{') st.pop();
					else{
						flag=false;
						break;
					}
				}
			}
			if(st.empty()&&flag) printf("yes\n");
			else printf("no\n");
		}
	
	return 0;
}

《算法笔记》6.8小节——C++标准模板库(STL)介绍->pair的常见用法详解

重心在哪里

#include<cstdio>
#include<utility>
using namespace std;
int main() {
	int n;
	while (scanf("%d", &n), n) {
		while (n--) {
			double a1, b1, a2, b2, a3, b3;
			scanf("%lf %lf %lf %lf %lf %lf", &a1, &b1, &a2, &b2, &a3, &b3);
			pair<double, double>a(a1, b1), b(a2, b2), c(a3, b3), res;
			res = make_pair((a.first + b.first + c.first) / 3.0, (a.second + b.second + c.second) / 3.0);
			printf("%.1f %.1f\n", res.first, res.second);
		}
	}

	return 0;
}

《算法笔记》6.9小节——C++标准模板库(STL)介绍->algorithm头文件下常用函数介绍

求最大最小数

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int n;
	while (scanf("%d", &n) != EOF) {
		vector<int> vi;
		for (int i = 0;i < n;++i) {
			int num;
			scanf("%d", &num);
			vi.push_back(num);
		}
		vector<int>::iterator it = vi.begin();
		sort(it, it + n);
		printf("%d %d\n", vi[n - 1], vi[0]);
	}
	return 0;
}

全排列

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main() {
	char str[10];
	while (scanf("%s", str) != EOF) {
		int len = strlen(str);
		do {
			printf("%s\n", str);
		} while (next_permutation(str, str + len));
		printf("\n");
	}
	return 0;
}

数组逆置

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

int main() {
	string str;
	while (getline(cin, str)) {
		reverse(str.begin(), str.end());
		cout << str << endl;
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值