PTA刷题日记13

1121 Damn Single (25 分)

毫无优化的处理方式,依旧没超时。。。

#include<bits/stdc++.h>
using namespace std;
vector<pair<int, int> > pa;
set<int> ans;
bool f[100005];
int main() {
	int n, m;
	scanf("%d",&n);
	for(int i = 0; i < n; i++) {
		int a, b;
		scanf("%d %d",&a, &b);
		pa.push_back(make_pair(a,b));
	}
	scanf("%d",&m);
	for(int i = 0; i < m; i++) {
		int a;
		scanf("%d",&a);
		f[a] = 1;
		ans.insert(a);
	}
	for(int i = 0; i < n; i++) {
		if(f[pa[i].first] && f[pa[i].second]) ans.erase(pa[i].first), ans.erase(pa[i].second);
	}
	printf("%d\n",ans.size());
	int i = 0;
	for(auto it: ans) {
		if(i++) printf(" ");
		printf("%05d",it);
	}
	return 0;
}

1122 Hamiltonian Cycle (25 分)

测试点2:出现的回路类似1 2 3 1 4 5 1(万一没对起点进行特判就出错了)

#include<bits/stdc++.h>
using namespace std;
bool v[305][305];
int cnt[305];

int main() {
	int n, m, a, b, k, st;
	scanf("%d %d",&n, &m);
	for(int i = 0; i < m; i++) {
		scanf("%d %d",&a, &b);
		v[a][b] = v[b][a] = 1;
	}
	scanf("%d",&k);
	while(k--) {
		bool f = 0;
		memset(cnt, 0, sizeof(cnt));
		scanf("%d",&a);
		if(a != n+1) f = 1;
		int pre;
		for(int i = 0; i < a; i++) {
			scanf("%d",&b);
			if(f) continue;
			if(!i) st = b;
			else if(v[pre][b] == 0) f = 1;
			if(cnt[b] && b != st) f = 1;
			cnt[b] ++;
			pre = b;
		}
		if(st != b || f || cnt[st] > 2) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}

1123 Is It a Complete AVL Tree (30 分)

类似1066的一题AVL树操作,没什么特别的难点,但是因为涉及函数很多,又有指针操作,写错了很难找错,写的时候要细心一点

#include<bits/stdc++.h>
using namespace std;
vector<int> ans;
int maxInd;
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 getH(node* root) {
	if(root == NULL) return 0;
	return root->height;
}

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

void update(node* &root) {
	root->height = max(getH(root->l) , getH(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(tmp);
	update(root);
	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);
			}
		}
	}
}

void levelorder(node* root) {
	queue<pair<node*,int> >q;
	q.push(make_pair(root, 1));
	while(q.size()) {
		pair<node*, int> now = q.front();
		q.pop();
		node* t = now.first;
		maxInd = max(maxInd, now.second);
		int ind1 = now.second*2, ind2 = ind1+1;
		ans.push_back(now.first->val);
		if(t->l != NULL) q.push(make_pair(t->l, ind1));
		if(t->r != NULL) q.push(make_pair(t->r, ind2));
	}
}


int main() {
	int n,a;
	scanf("%d",&n);
	node* root = NULL;
	for(int i = 0; i < n; i++) {
		scanf("%d",&a);
		insert(root, a);
//		cout<<root->val<<" "<<a<<endl;
	}
	levelorder(root);
	for(int i = 0; i < ans.size(); i++) {
		if(i) printf(" ");
		printf("%d",ans[i]);
	}
	if(maxInd == n) printf("\nYES");
	else printf("\nNO");
	return 0;
}

1126 Eulerian Path (25 分)

首先判断连通性,不连通一定不是欧拉图了,然后直接数度数为奇数的点即可,2个就是欧拉图,0个就是欧拉环,其他情况也不是欧拉图

#include<bits/stdc++.h>
using namespace std;
int degree[5005], even, odd;
bool v[5005];
vector<int> vec[5005];

void dfs(int x) {
	v[x] = 1;
	for(int i = 0; i < vec[x].size(); i++) {
		int y = vec[x][i];
		if(v[y]) continue;
		dfs(y);
	}
}


int main() {
	int n, m, a, b, num = 0;
	scanf("%d %d",&n, &m);
	for(int i = 0; i < m; i++) {
		scanf("%d %d",&a, &b);
		vec[a].push_back(b);
		vec[b].push_back(a);
		degree[a]++;
		degree[b]++;
	}
	for(int i = 1; i <= n; i++) {
		if(!v[i]) {
			dfs(i);
			num++;
		}
	}
	for(int i = 1; i <= n; i++) {
			if(i != 1) printf(" ");
			printf("%d", degree[i]);
			if(degree[i] % 2) odd++;
			else even++;
		}
		printf("\n");
	if(num > 1) printf("Non-Eulerian\n");
	else {
		if(odd == 0) printf("Eulerian\n");
		else if(odd == 2) printf("Semi-Eulerian\n");
		else printf("Non-Eulerian\n");	
	}
	
	return 0;
}

1128 N Queens Puzzle (20 分)

判断行列是否重复,没有难点,如果像我一样用数组,记得数组开大点,否则是报答案错误,而不是段错误,找了好久

#include<bits/stdc++.h>
using namespace std;
bool row[1005], line1[2005], line2[2005];

int main() {
	int n, k, a;
	scanf("%d",&k);
	while(k--) {
		bool f = 0;
		memset(row, 0, sizeof(row));
		memset(line1, 0, sizeof(line1));
		memset(line2, 0, sizeof(line2));
		scanf("%d",&n);
//		int pre = -2;
		for(int i = 1; i <= n; i++) {//第i列 
			scanf("%d",&a);//第a行 
			if(f) continue;
			if(row[a] || line1[a+i] || line2[(n+i-a)%(2*n)]) f = 1;
			row[a] = line1[a+i] = line2[(n+i-a)%(2*n)] = 1;
		}
		if(f) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
/*
5
8 4 6 8 2 7 1 3 5
9 4 6 7 2 8 1 9 5 3
6 1 5 2 6 4 3
5 1 3 5 2 4
6 1 5 3 6 2 4
*/

1129 Recommendation System (25 分)

直接用set排序了,并没有超时。。。
就是每次注意一下先删再加和输出的数不要超过k个即可

#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5;
set<int> id[N];
int num[N], ma;

int main() {
	int n, k, a;
	scanf("%d %d",&n, &k);
	for(int i = 0; i < n; i++) {
		scanf("%d",&a);
		if(i) {
			printf("%d:",a);
			for(int i = 0, j = ma; i < k && j > 0; j--) {
				for(auto it: id[j]){
					if(i < k)i++;
					else break;
					printf(" %d",it);
					
				}
			}
			printf("\n");
		}
		id[num[a]].erase(a);
		num[a]++;
		ma = max(ma, num[a]);
		id[num[a]].insert(a);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值