PAT(甲级)2017年春季考试

PAT(甲级)2017年春季考试

PAT 1124 Raffle for Weibo Followers (20 分)

【解题思路】

微博抽奖,输入给定第一个中奖用户编号,以及后面每隔多少个用户给一个奖。

用一个循环输入,记录当前是第几条记录,判断当前用户是否中奖,输出即可。

需要注意的是,已经中奖的用户不再重复中奖,我们使用一个set,将中奖用户加入,如果后面遇到相同的字符串则跳过。

【满分代码】

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int m,n,s,temp=0;
	string t;
	set<string> st;
	cin>>m>>n>>s;
	while(m--)
	{
		cin>>t;
		if(st.count(t)==0)
			temp++;
		else continue;//没加上这句也能过,测试数据有漏洞
		if(temp-s>=0&&(temp-s)%n==0)
		{
			cout<<t<<endl;
			st.insert(t);
		}
	}
	if(st.size()==0)
		cout<<"Keep going..."<<endl;
	return 0;
}

PAT 1125 Chain the Ropes (25 分)

【解题思路】

每次选取两根绳子,各自做成环后套在一起,即得到的新绳子长度为原来两段绳长之和的一半。

显然,越长的绳子被折的次数越少越好。

我们采用贪心,每次选取最短的两条绳合并,最终得到的一条即为最优答案。

这里我们采用优先队列,当然直接用数组排序,从头到尾处理也可。因为,选取最短的两根绳长和的一半得到的新绳,和没使用过的绳相比,肯定还是最短的。

【满分代码】

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	double t;
	priority_queue<double,vector<double>,greater<double>> q;
	cin>>n;
	while(n--)
	{
		cin>>t;
		q.push(t);
	}
	while(q.size()>1)
	{
		double a=q.top();
		q.pop();
		double b=q.top();
		q.pop();
		q.push((a+b)/2);
	}
	cout<<(int)q.top()<<endl;
	return 0;
}

PAT 1126 Eulerian Path (25 分) 欧拉路

【解题思路】

判断一个图是否存在欧拉路

求出并输出每个点的度数

注意还需要判断整个图是否连通

当图连通,且每个点度数都为偶数,输出“Eulerian”。

当图连通,且有且只有两个点度数为奇数,输出“Semi-Eulerian”。

其他情况,输出“Non-Eulerian”。

【满分代码】

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int vis[505],d[505];//每个点的度数 
vector<int> g[505];//邻接表 
int n,m,u,v,sum=0,cnt=0;
void dfs(int t)
{
	sum++;
	vis[t]=1;
	for(int i=0;i<g[t].size();i++)
		if(!vis[g[t][i]])
			dfs(g[t][i]);
}//判断整个图是否连通 
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	while(m--)
	{
		cin>>u>>v;
		g[u].emplace_back(v);
		g[v].emplace_back(u);
		d[u]++;
		d[v]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(d[i]%2) cnt++;
		i!=1?cout<<' '<<d[i]:cout<<d[i];
	}
	dfs(1);
	if(sum==n&&cnt==0)
		cout<<endl<<"Eulerian"<<endl;
	else if(sum==n&&cnt==2)
		cout<<endl<<"Semi-Eulerian"<<endl;
	else
		cout<<endl<<"Non-Eulerian"<<endl;
	return 0;
}

PAT 1127 ZigZagging on a Tree (30 分) 二叉树

【解题思路】

经典的二叉树问题

输入给出二叉树的中序遍历后序遍历,要求输出层序遍历

输出还有个要求,按照“Z”字形,奇数层从右往左,偶数层从左往右(这里把根节点作为第1层)。

我们在BFS层序遍历的时候,将每一层的结点存入vector中,输出的时候按照层数的奇偶来输出就可以了。

【满分代码】

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
int in[35],post[25];
vector<int> vec[35];
struct node
{
	int data;
	node *lchild,*rchild;
};
node* build(int postL,int postR,int inL,int inR)
{
	if(postL>postR)
		return NULL;
	node *root=new node;
	root->data=post[postR];
	int k;
	for(k=inL;k<=inR;k++)
		if(in[k]==post[postR])
			break;
	int num=k-inL;
	root->lchild=build(postL,postL+num-1,inL,k-1);
	root->rchild=build(postL+num,postR-1,k+1,inR);
	return root;
}//递归建二叉树 
void BFS(node* root)
{
	cout<<root->data;//输出根节点的值 
	queue<node*> q;
	q.push(root);
	int level=0;//当前层数(根节点为第1层) 
	while(!q.empty())
	{
		level++;
		int size=q.size();//当前层上的结点个数 
		while(size--)
		{
			node* t=q.front();
			q.pop();
			vec[level].emplace_back(t->data);
			if(t->lchild)
				q.push(t->lchild);
			if(t->rchild)
				q.push(t->rchild);
		}
	}
	for(int i=2;i<=level;i++)
	{
		if(i%2==0)//偶数层从左往右输出 
		{
			for(int j=0;j<vec[i].size();j++)
				cout<<" "<<vec[i][j];
		}
		else//奇数层从右往左输出 
		{
			for(int j=vec[i].size()-1;j>=0;j--)
				cout<<" "<<vec[i][j];
		}
	}
}//层序遍历并输出 
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>in[i];
	for(int i=0;i<n;i++)
		cin>>post[i];
	node *root=build(0,n-1,0,n-1);
	BFS(root);
	return 0; 
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

球王武磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值