PTA刷题日记07

1061 Dating (20 分)

没啥难度的字符串处理,个人感觉是要输出时间(前面补零)的各种形式都不要用字符串,很容易忘掉几个0,然后就一直错,我在我的代码里标记了,顺便放一个不用愚蠢的补零,直接printf的时候处理的代码(这种比较好)

#include<bits/stdc++.h>
using namespace std;
string week[10] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};

int main() {
	string a, b, c, d, ans = "";
	cin >> a >> b >> c >> d;
	int l1 = min(a.length(), b.length());
	int l2 = min(c.length(), d.length());
	int num = 0;
	for(int i = 0; i < l1; i++) {
		if(num > 1) break;
		if(!num) {
			if('A'<=a[i] && a[i] <= 'G' && a[i] == b[i]) {
				int ind = a[i] - 'A';
				ans += week[ind];
				num++;
			}
		}
		else {
			if((isdigit(a[i]) ||('A'<=a[i] && a[i] <= 'N')) && a[i] == b[i]) {
				ans += " ";
				if(a[i] < 'A') ans += '0', ans += a[i];//这里一定要补 
				else {
					int num = a[i] - 'A' + 10;
					char ch1 = '0'+num/10, ch2 = '0'+ num % 10;
					ans += ch1;
					ans += ch2;
				}
				num++;
			}
		}
	}
	for(int i = 0; i < l2; i++) {
		if(isalpha(c[i]) && c[i] == d[i]) {
			ans += ":";
			char ch1 = '0'+ i/10, ch2 = '0'+ i % 10;
			ans += ch1;//有可能是0 
			ans += ch2;
			break;
		}
	}
	cout<<ans<<endl;
	return 0;
}
/*
3485djFkxh40hG3 
2984akFfkkk2gg3dsb 
s&hgafdk2984akDfkkkkggEdsb
d&Hyscvnm2984akDfkkkkggEdsb
*/

好一点的代码

#include<bits/stdc++.h>
using namespace std;
map<char,string>mp;
void init()
{
	mp['A'] = "MON";mp['B'] = "TUE";
	mp['C'] = "WED";mp['D'] = "THU";
	mp['E'] = "FRI";mp['F'] = "SAT";
	mp['G'] = "SUN";
}
int main()
{
	string s1,s2,s3,s4;
	cin>>s1>>s2>>s3>>s4;
	init();
	int minn = min(s1.length(),s2.length()),i;
	for(i = 0; i < minn ;i++)
	{
		if(s1[i] == s2[i] && s1[i] >='A' && s1[i] <= 'G')
		{
			cout<<mp[s1[i]];
			break;
		}
	}
	for(++i; i < minn;i++)
	{
		if(s1[i] == s2[i])
		{
			if(s1[i] >= 'A' && s1[i] <= 'N')
			{
				printf(" %02d:",(10+s1[i]-'A'));
				break;
			}	
			else if(isdigit(s1[i]))
			{
				printf(" %02d:",s1[i]-'0');
				break;
			}	
		}
	}
	minn = min(s3.length(),s4.length());
	for(int i = 0; i< minn ;i++)
	{
		if(s3[i] == s4[i] && isalpha(s3[i]))
		{
			printf("%02d\n",i);
			return 0;
		}	
	}
	return 0;
}

1062 Talent and Virtue (25 分)

没啥难点的排序,理解提议即可,分成四组,两歌分数都没过最低线的不计入排序

#include<bits/stdc++.h>
using namespace std;
//const int N = 1e5 + 5;
struct node{
	int id, vir, tal, total;
	friend bool operator<(node a, node b) {
		if(a.total == b.total) {
			if(a.vir == b.vir) return a.id < b.id;
			else return a.vir > b.vir;
		}
		else return a.total > b.total;
	}
};
vector<node> per[5];


int main() {
	int n, low, high;
	cin >> n >> low >> high;
	int cnt = 0;
	for(int i = 0; i < n; i++) {
		int a, b , c;
		cin >> a >> b >> c;
		if(b < low || c < low) continue;
		else if(b >= high && c >= high) per[0].push_back({a,b,c,b+c});
		else if(b >= high) per[1].push_back({a,b,c,b+c});
		else if(b >= c) per[2].push_back({a,b,c,b+c});
		else per[3].push_back({a,b,c,b+c});
		cnt++;
	}
	cout<<cnt<<endl;
	for(int i = 0; i < 4; i++) {
		sort(per[i].begin(), per[i].end());
		int l = per[i].size();
		for(int j = 0; j < l; j++) {
			printf("%07d %d %d\n",per[i][j].id,per[i][j].vir,per[i][j].tal);
		}
	}
	return 0;
}

1063 Set Similarity (25 分)

经过多次超时得到的教训就是不要因为set好用就多次用,一旦这样就要超时,set内部实现是红黑树,插入虽然是logn,但是插的元素多了就出事了,所以在一开始就用一个num数组记录好相关集合中的元素数量,最后相加减去相同的即为总数

#include<bits/stdc++.h> 
using namespace std;
set<int> a[55];
int num[55];

int main() {
	int n, m, k, c;
	scanf("%d",&n);
	for(int i = 1; i <= n; i++) {
		scanf("%d",&m);
		for(int j = 0; j < m; j++) {
			scanf("%d",&c);
			a[i].insert(c);
		}
		num[i] = a[i].size();
	}
	scanf("%d",&k);
	for(int i = 0; i < k; i++) {
		int s1, s2, tot;
		double con = 0;
		scanf("%d %d",&s1, &s2);
		map<int,bool> mp;
		for(auto it: a[s1]) {
			mp[it] = 1;
		}
		for(auto it: a[s2]) {
			if(mp.count(it) && mp[it] == 1) con++, mp[it] = 0;
		}
		tot = num[s1] + num[s2] - con;
		printf("%.1lf%%\n",con/tot*100);
	}
	return 0;
}

1064 Complete Binary Search Tree (30 分)

类似前中序建树一样的递归建树,然后层次遍历并输出

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
vector<int> ans;
int arr[N];
struct node {
	int val;
	node *l, *r;
};

node* create(int l, int r) {
	if(l > r) return NULL;
	node *root = new node;
	int num = r - l + 1, lay = log(num)/log(2), a = pow(2, lay) - 1;
	int rest = num - a, nl, nr;
	a = (a-1) / 2;
	if(rest <= pow(2, lay-1)) nl = a + rest, nr = a;
	else {
		nl = a + pow(2, lay-1);
		nr = a + rest - pow(2, lay-1);
	}
	root->val = arr[nl+l];
	root->l = create(l, l+nl-1);
	root->r = create(l+nl+1, r);
	return root;
}

void levelorder(node *root) {
	queue<node*> q;
	q.push(root);
	while(q.size()) {
		node* now = q.front();
		q.pop();
		if(now != NULL) ans.push_back(now->val);
		if(now->l != NULL) q.push(now->l);
		if(now->r != NULL) q.push(now->r);
	}
}
int main() {
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; i++) {
		scanf("%d",arr+i);
	}
	sort(arr, arr+n);
	node* root = create(0, n-1);
	levelorder(root);
	for(int i = 0; i < ans.size(); i++) {
		if(i) printf(" ");
		printf("%d",ans[i]);
	}
	return 0;
}

1066 Root of AVL Tree (25 分)

标准的AVL树操作

#include<bits/stdc++.h>
using namespace std;
struct node{
	int val, height;
	node *l, *r;
};

node* New(int x) {
	node* t = new node;
	t->val = x;
	t->height = 1;
	t->l = t->r = NULL;
	return t;
}

int getheight(node* root) {
	if(root == NULL) return 0;
	return root->height;
}

int getB(node* root) {
	return getheight(root->l) - getheight(root->r);
}

void update(node* &root) {
	root->height = max(getheight(root->l), getheight(root->r)) + 1;
}

void L(node* &root) {
	node* tmp = root->r;
	root->r = tmp->l;
	tmp->l = root;
	update(root); update(tmp);
	root = tmp;
}

void R(node* &root) {
	node* tmp = root->l;
	root->l = tmp->r;
	tmp->r = root;
	update(root); update(tmp);
	root = tmp;
}

void insert(node* &root, int x) {
	if(root == NULL) {
		root = New(x);
		return;
	}
	if(root->val > x) {
		insert(root->l, x);
		update(root);
		if(getB(root) == 2) {
			if(getB(root->l) == 1) {
				R(root);
			}
			else if(getB(root->l) == -1) {
				L(root->l);
				R(root);
			}
		}
	}
	else {
		insert(root->r, x);
		update(root);
		if(getB(root) == -2) {
			if(getB(root->r) == -1) L(root);
			else if(getB(root->r) == 1) {
				R(root->r);
				L(root);
			}
		}
	}
}

int main() {
	int n, a;
	scanf("%d",&n);
	node* root = NULL;
	for(int i = 0; i < n; i++) {
		scanf("%d",&a);
		insert(root, a);
	}
	printf("%d",root->val);
	return 0;
}

1067 Sort with Swap(0, i) (25 分)

就是判断给定的数组中有几个循环,{3,1,2}就是一个循环,因为3在位置1上,1在位置2上,2在位置3上,是串起来的,已经在自己位置上单个数字的不计入,然后对有0和无0的循环进行一点处理并求和就是最终答案

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

int main() {
	int n, a, ans = 0;
	scanf("%d",&n);
	for(int i = 0; i < n; i++) {
		scanf("%d", &f[i]);
		if(f[i] == i) v[i] = 1;
	}
	for(int i = 0; i < n; i++) {
		if(!v[i]) {
			int b = i, haso = 1, cnt = 0;
			while(!v[b]) {
				cnt++;
				if(b == 0) haso = -1;
				v[b] = 1;
				b = f[b];
			}
			ans += cnt + haso;
		}
		
	}
	cout<<ans<<endl;
	return 0;
}

1068 Find More Coins (30 分)

用dfs最后一个点超时,如果不强求满分我觉得这个就可以了,毕竟我真的对dp很不熟,最后看别人的博客特判一下如果所有点都达不到要求直接返回即可通过,就小技巧吧。。。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int n, m, arr[N];
vector<int> ans;

void dfs(int now, int v) {
	if(v > m) return;
	if(v == m) {
		for(int i = 0; i < ans.size(); i++) {
			if(i) printf(" ");
			printf("%d", ans[i]);
		}
		exit(0);
	}
	for(int i = now+1; i <= n; i++) {
		ans.push_back(arr[i]);
		dfs(i, v + arr[i]);
		ans.pop_back();
	}
}

int main() {
	scanf("%d %d", &n, &m);
	int total = 0;
	for(int i = 1; i <= n; i++) {
		scanf("%d", arr+i);
		total += arr[i];
	}
	sort(arr+1, arr+1+n);
	if(m && total >= m) dfs(0, 0);
	printf("No Solution");
	return 0;
}

1069 The Black Hole of Numbers (20 分)

测试点5为输入6147的情况
要考虑边界值!要考虑边界值!要考虑边界值!(包括n=0,循环不进行等情形)

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

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

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

string fun(int n) {
	string t;
	while(n) {
		int b = n % 10;
		t += b + '0';
		n /= 10;
	}
	for(int i = t.length(); i < 4; i++) {
		t += '0';
	}
	return t;
}

int main() {
	string a, b;
	int n1, n2;
	cin >> a;
	int dif = s2i(a);
	do {
		b = fun(dif);
		sort(b.begin(), b.end());
		a = b;
		reverse(a.begin(), a.end());
		n1 = s2i(a), n2 = s2i(b);
		dif = n1 - n2;
		if(dif == 0) {
			printf("%04d - %04d = %04d\n", n1, n2, dif);
			break;
		}
		printf("%04d - %04d = %04d\n", n1, n2, dif);
	}
	while(dif != 6174);
	return 0;
}

1070 Mooncake (25 分)

这题测试点2的错误在于月饼的吨数也必须是浮点数,仔细看了一眼题目确实没说是整数,但是后面的rest我用的是整数仍然能过所有点,所以我推测问题还是计算优先级rate的时候产生的,所以以后这里也要小心

#include<bits/stdc++.h>
using namespace std;
struct node{
	double ton, p, rate;
	friend bool operator<(node a, node b) {
		return a.rate > b.rate;
	}
}moon[1005];

int main() {
	int n, d;
	scanf("%d %d",&n, &d);
	for(int i = 0; i < n; i++) scanf("%lf", &moon[i].ton);
	for(int i = 0; i < n; i++) {
		scanf("%lf",&moon[i].p);
		moon[i].rate = moon[i].p / moon[i].ton;
	}
	sort(moon, moon+n);
	int rest = d;
	double ans = 0;
	for(int i = 0; i < n; i++) {
		if(rest > moon[i].ton) {
			rest -= moon[i].ton;
			ans += moon[i].p;
		}
		else {
			ans += rest * moon[i].p / moon[i].ton;
			break;
		}
	}
	printf("%.2f", ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值