PTA刷题日记08

1071 Speech Patterns (25 分)

处理连续字符(只包含数字,小写字母,大写字母),一旦遇到别的字符就单词到这结束,值得注意的是字符串比较前要判空,否则有问题,还有如果这句话最后一个单词要注意,可能会没处理

#include<bits/stdc++.h> 
using namespace std;
map<string, int> mp;
int ma = -1;
string ans;

int main() {
	char ch = getchar();
	string word = "";
	while(ch != '\n') {
		if(isalnum(ch)) {
			if(isupper(ch)) ch += 32;
			word += ch;
		}
		else {
			if(!word.empty()) {
				mp[word]++;	
				if(mp[word] > ma) {
					ma = mp[word];
					ans = word;
				}
				else if(mp[word] == ma && ans > word) ans = word;
			}
			word = "";
		}
		ch = getchar();
	}
	if(!word.empty()) {
		mp[word]++;
		if(mp[word] > ma) {
			ma = mp[word];
			ans = word;
		}
		else if(mp[word] == ma && ans > word) ans = word;	
	}
	cout<<ans<<" "<<ma<<endl;
	return 0;
}

1073 Scientific Notation (20 分)

本来觉得应该有问题,比如+0.00E+10这种该怎么考虑,但是我这么写过了,不知道是没有这样的测试用例还是默认这样就是正确的
就是找到‘.’和‘E’的位置,然后把非指数部分的数字都记录下来作为最终结果的一部分,然后根据指数部分的计算小数点的移动方向和移动步长然后具体操作即可

#include<bits/stdc++.h>
using namespace std;

int s2i(string s) {
	int n;
	stringstream ss;
	ss << s;
	ss >> n;
	return n;
}

int main() {
	char ch = getchar();
	string s, t;
	cin >> s;
	int p1, p2, p3, inc, step;
	p1 = s.find('.');
	p2 = s.find('E');
	if(s[p2+1] == '+') inc = 1;
	else inc = -1;
	step = s2i(s.substr(p2+2, s.length())) * inc;
	p3 = p1 + step;
	for(int i = 0; i < p2; i++) {
		if(isdigit(s[i])) t += s[i];
	}
	if(inc < 0) {
		if(p3 <= 0) {
			for(int i = 0; i > p3; i--) {
				t = '0' + t;
			}
			t = "0." + t;
		}
		else t.insert(p3, ".");
	}
	else {
		int l = t.length();
		if(p3 >= l) {
			for(int i = l; i < p3; i++) {
				t += '0';
			}
		}
		else t.insert(p3, ".");
	}
	if(ch == '+') cout<<t<<endl;
	else cout<<ch<<t<<endl;
	return 0;
}

1074 Reversing Linked List (25 分)

链表,最方便的方法就是先记录前后关系,再从头节点开始把元素按顺序依次放入一个数组中
这题比较方便的写法就是直接使用reverse函数,但是我没想到呜呜
还有测试点6是给定的节点中有的并不在链表里,所以在按头结点放入元素之后要重新计算链表的长度

#include<bits/stdc++.h> 
using namespace std;
const int N = 1e5 + 5;
int val[N], ch[N], List[N];

int main() {
	int n, k, head, nxt, t, th, tn;
	scanf("%d %d %d",&head, &n, &k);
	for(int i = 1; i <= n; i++) {
		scanf("%d %d %d",&th, &t, &tn);
		val[th] = t;
		ch[th] = tn;
	}
	int now = head, l = 1;
	for(; l <= n; l++) {
		if(now == -1)  break;
		List[l] = now;
		now = ch[now];
	}
	l--;
	int m = l / k * k;
	for(int i = 1; i*k <= l; i ++) {
		int p = i*k;
		for(int j = 0; j < k; j++, p--) {
			if(j || i != 1) printf("%05d\n", List[p]);
			printf("%05d %d ", List[p], val[List[p]]);
		}
	}
	for(int i = m+1; i <= l; i++) {
		printf("%05d\n%05d %d ", List[i], List[i], val[List[i]]);
	}
	printf("-1");
	return 0;
} 

1075 PAT Judge (25 分)

这题理解并不难,但是是一道很烦人的排序题,有很多需要注意的地方,稍有不慎就是错
1.提交0分和提交-1不一样
2.如果这个人被计入了ranklist那么提交-1显示就是0,只有没提交过的才是-
3.拿了满分的题不要重复计算,否则排序出错
4.如果你像我一样把初始设为-2,提交没成功设为-1,其他直接表示,注意计算total的时候如果去减-1或者-2都是错误的,必须减0
垃圾代码如下

#include<bits/stdc++.h>
using namespace std;
int p[10];
struct node{
	int id, total,num;
	int sco[10];
	bool f; 
	node(){
		for(int i = 0; i < 10; i++) sco[i] = -2;
		id = total = num = 0;
		f = 0;
	}
	friend bool operator < (node a, node b) {
		if(a.total == b.total) {
			if(a.num == b.num) return a.id < b.id;
			else return a.num > b.num;
		}
		else return a.total > b.total;
	}
};
vector<node> per;
map<int, int> rec;

int main() {
	int n, k, m, cnt = 0, rk = 0;
	cin >> n >> k >> m;
	int a,b,c;
	for(int i = 1; i <= k; i++) cin >> p[i];
	for(int i = 0; i < m; i++) {
		cin >> a >> b >> c;
		if(rec.count(a) == 0) {
			node tem;
			rec[a] = cnt++;
			tem.id = a, tem.sco[b] = c;
			if(c >= 0) tem.f = 1, tem.total = c;
			if(c == p[b]) tem.num = 1;
			per.push_back(tem);	
		}
		else {
			int ind = rec[a];
			if(c >= per[ind].sco[b]) {
				if(c == -1);
				else if(per[ind].sco[b] == -2 || per[ind].sco[b] == -1) 
					per[ind].total += c, per[ind].f = 1;
				else per[ind].total += c - per[ind].sco[b], per[ind].f = 1;
				if(c == p[b] && per[ind].sco[b] != c) per[ind].num++;
				per[ind].sco[b] = c;
			}
		}
	}
	sort(per.begin(), per.end());
	int last = -1, lazy = 1;
	for(int i = 0; i < cnt; i++) {
		if(per[i].f == 0) continue;
		if(last == per[i].total) lazy++;
		else rk += lazy, lazy = 1;
		printf("%d %05d %d",rk, per[i].id,per[i].total);
		for(int j = 1; j <= k; j++) {
			if(per[i].sco[j] == -2) printf(" -");
			else if(per[i].sco[j] == -1) printf(" 0");
			else printf(" %d",per[i].sco[j]);
		}
		printf("\n");
		last = per[i].total;
	}
	return 0;
}
/*
7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 2 -1
00007 2 25
00005 1 20
00002 2 2
00005 1 19
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00007 2 25
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 1 15
00004 2 0
*/

1077 Kuchiguse (20 分)

一个字符串翻转的题,会偷懒的人直接用内置函数,string和char数组应该都是可以用reverse翻转的(reverse(a.begin(), a.end())和reverse(a,a+n)),所以其实char数组更灵活,不过string用起来方便。。。
还有一个注意点是getchar()把cin后面那个换行符吃掉,否则读入会出错

#include<bits/stdc++.h>
using namespace std;

string common(string a, string b) {
	string ans = "";
	int l = min(a.length(), b.length());
	for(int i = 0; i < l; i++) {
		if(a[i] == b[i]) ans += a[i];
		else break;
	}
	return ans;
}

int main() {
	int n;
	string a, b, com;
	bool f = 0;
	cin >> n;
	getchar();
	getline(cin , com);
	reverse(com.begin(), com.end());
	for(int i = 1; i < n; i++) {
		getline(cin, b);
		if(f) continue;
		reverse(b.begin(), b.end());
		com = common(com, b);
		if(com.empty()) f = 1;
	}
	if(f) printf("nai\n");
	else {
		reverse(com.begin(), com.end());
		cout<<com<<endl;
	}
	return 0;
}

1078 Hashing (25 分)

这题压根没看懂那个Quadratic probing是平方探测,而且我其实也不知道平方探测到底怎么实现的,所以hash还是得再看看呀,然后就按照题意正常编写即可

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
unordered_map<int, bool>mp;
int arr[N];

bool isp(int n) {
	if(n < 2) return false;
	for(int i = 2; i <= sqrt(n); i++) {
		if(n % i == 0) return false;
	}
	return true;
}

int main() {
	int m, n, tem;
	scanf("%d %d",&m,&n) ;
	if(!isp(m)) {
		m++;
		for(; !isp(m); m++);
	}
	for(int i = 0; i < n; i++) {
		scanf("%d",&tem);
		for(int j = 0; j < m; j++) {
			int p = (tem + j*j) % m;
			if(mp.count(p) == 0) {
				mp[p] = 1;
				arr[i] = p;
				break;
			}
			else arr[i] = -1;	
		}
	}
//	cout<<m<<endl;
	for(int i = 0; i < n; i++) {
		if(i) printf(" ");
		if(arr[i] == -1) {
			printf("-");
		}
		else printf("%d",arr[i]);
	}
	return 0;
}

1079 Total Sales of Supply Chain (25 分)

测试点1是只有根节点的情况,用bfs遍历一遍树即可

#include<bits/stdc++.h> 
using  namespace std;
const int N = 5e5 + 5;
int n, tot, head[N], ver[N], nxt[N], num[N], isr[N];
double p, r, price[N], ans;

void add(int x, int y) {
	ver[++tot] = y;
	nxt[tot] = head[x], head[x] = tot;
}

void bfs() {
	queue<int> q;
	q.push(0);
	while(q.size()) {
		int x = q.front();
		q.pop();
		for(int i = head[x]; i; i = nxt[i]) {
			int y = ver[i];
			price[y] = price[x] * r;
			if(isr[y]) ans = ans + price[y] * num[y];
			else q.push(y);
		}
	}
}

int main() {
	scanf("%d %lf %lf",&n, &price[0], &r);
	r = 1 + r/100;
	int k, id;
	for(int i = 0; i < n; i++) {
		scanf("%d",&k);
		if(k) {
			for(int j = 0; j < k; j++) {
				scanf("%d",&id);
				add(i, id);
			}
		}
		else {
			scanf("%d",&num[i]);
			isr[i] = 1;
		}
	}
	bfs();
	if(n == 1) printf("%.1lf",price[0]*num[0]);
	else printf("%.1lf",ans);
	return 0;
}
/*
10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

1 1.8 1
0 3
*/

1080 Graduate Admission (30 分)

排序题,处理好就行了,自己理解题意吧(锻炼英语),就是最后学校输出录取人的id要从小到大排别忘了

#include<bits/stdc++.h>
using namespace std;
int cap[105], rk[105];
struct node{
	int id, ge, gi, rk;
	double g;
	int s[10];
	friend bool operator <(node a, node b) {
		if(a.g == b.g) return a.ge > b.ge;
		else return a.g > b.g;
	}
};
vector<node> app;
set<int> sch[105];


int main() {
	int n, m, k;
	cin >> n >> m >> k;
	for(int i = 0; i < m; i++) {
		cin >> cap[i];
	}
	node temp;
	for(int i = 0; i < n; i++) {
		cin >> temp.ge >> temp.gi;
		temp.g = (1.0*temp.ge + temp.gi) / 2;
		temp.id = i;
		for(int j = 0; j < k; j++) cin >> temp.s[j];
		app.push_back(temp);
	}
	sort(app.begin(), app.end());
	int rank = 0, lazy = 1, lge = -1;
	double lg = -1;
	for(int i = 0; i < n; i++) {
		if(lg == app[i].g && lge == app[i].ge) lazy++;
		else rank += lazy, lazy = 1;
		for(int j = 0; j < k; j++) {
			int ind = app[i].s[j];
			if(cap[ind] > sch[ind].size() || rk[ind] == rank) {
				sch[ind].insert(app[i].id);
				rk[ind] = rank;
				break;
			}
		} 
		lg = app[i].g, lge = app[i].ge;
	}
	for(int i = 0; i < m; i++) {
		if(sch[i].size()) {
			int j = 0;
			for(auto it: sch[i]) {
				if(!j++) cout<<it;
				else cout<<" "<<it;
			}
			cout<<endl;
		} 
		else cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值