PAT(甲级)2011年秋仿真卷

21 篇文章 1 订阅

PAT(甲级)2011年秋仿真卷

发现PAT练习的网站上可以购买往年的真题试卷进行练习,购买时光机以后还可以看到考试的实时榜单,和当时现场考试的考生同场竞技。

最近开始为准备9月的PAT考试复习刷题,争取能够取得理想的成绩!

A World Cup Betting (20 分)

【解题思路】

算是签到题,没什么技术含量。

【满分代码】

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	double a,b,c,odds=1;
	for(int i=1;i<=3;i++)
	{
		scanf("%lf%lf%lf",&a,&b,&c);
		if(a>b&&a>c)
		{
			printf("W ");
			odds*=a;
		}
		else if(b>a&&b>c)
		{
			printf("T ");
			odds*=b;
		}
		else if(c>a&&c>b)
		{
			printf("L ");
			odds*=c;
		}
	}
	printf("%.2f\n",(odds*0.65-1)*2);
	return 0;
}

B The Best Rank (25 分)

【解题思路】

很显然这是一道排序题,我们用结构体存数据,使用cmp函数进行排序。要注意的是,这道题细节很多。

比如当两个人分数相同时,排名的值相同,比如如果有4个人,中间2个人当前课程的分数并列,那么他们当前课程的排名分别是1,2,2,4。

另外要注意在选取最优排名时,各门科目的优先级,即A > C > M > E。为方便起见,我们数组下标1到3分别表示C、M、E三门课,下标0计算平均分A。

排序的时候用到一个小技巧,因为我们需要按照不同科目进行排序,统计名次,我们用一个全局变量sub,这样我们修改sub的值,使用cmp函数就能按照对应科目进行排序了。

最后我们使用一个map来记录每个学号是否存在,同时可以记录最终这个学号在结构体数组当中的位置。查询时,若输入的学号存在,输出答案即可,否则输出N/A。

【满分代码】

#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm> 
using namespace std;
struct node
{
	string s;
	int grade[4],rank[4],best;
	char ans;
}stu[2005];
int sub=0;
bool cmp(node a,node b)
{
	return a.grade[sub]>b.grade[sub];
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		cin>>stu[i].s>>stu[i].grade[1]>>stu[i].grade[2]>>stu[i].grade[3];
		stu[i].grade[0]=stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3];
	}
	for(int i=0;i<4;i++)
	{
		sub=i;
		sort(stu,stu+n,cmp);
		stu[0].rank[i]=1;
		for(int j=1;j<n;j++)
		{
			if(stu[j].grade[i]==stu[j-1].grade[i])
				stu[j].rank[i]=stu[j-1].rank[i];
			else
				stu[j].rank[i]=j+1;
		}
	}
	map<string,int> mp;
	for(int i=0;i<n;i++)
	{
		mp[stu[i].s]=i;
		int best=0,temp=2005;
		for(int j=0;j<4;j++)
		{
			if(stu[i].rank[j]<temp)
			{
				temp=stu[i].rank[j];
				best=j;
			}
		}
		stu[i].best=temp;
		if(best==0)
			stu[i].ans='A';
		else if(best==1)
			stu[i].ans='C';
		else if(best==2)
			stu[i].ans='M';
		else
			stu[i].ans='E';
	}
	string s;
	for(int i=0;i<m;i++)
	{
		cin>>s;
		if(mp.count(s))
			cout<<stu[mp[s]].best<<" "<<stu[mp[s]].ans<<endl;
		else
			cout<<"N/A"<<endl;
	}
	return 0;
}

C Battle Over Cities (25 分)

【解题思路】

给出一个无向图,需要我们求的是,去掉某个点后,使得剩下的所有点连通,至少需要添加几条边。

显然,我们只要求去掉那个点之后,一共有几个连通分量,需要添加的最少边数即为连通分量数-1

这道题和3月14日的牛客网训练联盟热身训练赛第二场的F Interstellar Love题差不多。

采用并查集或者DFS都能够求得连通分量数,下面分别给出两种做法的代码。

【满分代码1 并查集】

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=1010;
vector<int> G[maxn];//邻接表 
int n,m,k,a,b,c,p[maxn],vis[maxn];
int find(int x)
{
	return p[x]==x?x:p[x]=find(p[x]);
}//并查集 
void unio(int a,int b)
{
	int x=find(a),y=find(b);
	if(x!=y) p[x]=y;
}
void init()
{
	for(int i=1;i<=n;i++)
	{
		p[i]=i;
		vis[i]=0;
	}
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	for(int t=0;t<k;t++)
	{
		cin>>c;
		init();
		for(int i=1;i<=n;i++)
		{
			int size=G[i].size();
			for(int j=0;j<size;j++)
			{
				if(i!=c&&G[i][j]!=c)
					unio(i,G[i][j]);
			}
		}
		int ans=0;
		/* 
		for(int i=1;i<=n;i++)
			if(i!=c) find(i);//注意是find(i)不是p[i] 
		sort(p+1,p+n+1);
		for(int i=1;i<=n;i++)
			if(p[i]!=p[i-1]&&p[i]!=c)
				ans++;
		cout<<ans-1<<endl;
		*/
		for(int i=1;i<=n;i++)
		{
			if(i==c) continue;
			int fa=find(i);
			if(!vis[fa])
			{
				ans++;
				vis[fa]=1;
			}
		}
		cout<<ans-1<<endl;
	}
	return 0;
}

【满分代码2 DFS】

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int num=2000005;//注意:链式前向星,无向图,开两倍(最大边数1000*1000的两倍)!!! 
int n,m,k,a,b,c,ans=0;//ans为连通分量数量 
struct edge
{
	int to,next;
}edge[num];
int cnt,head[num];
void init()
{
	for(int i=0;i<num;i++)
	{
		edge[i].next=-1;
		head[i]=-1;
	}
	cnt=0;
}
void addedge(int u,int v)
{
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}//链式前向星存图 

int vis[1010],flag;
void dfs(int x)
{
	for(int i=head[x];i!=-1;i=edge[i].next)
		if(edge[i].to!=c)
		{
			if(vis[edge[i].to]==0)
			{
				vis[edge[i].to]=1;
				dfs(edge[i].to);
			}
		}
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>k;
	init();
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b;
		addedge(a,b);
		addedge(b,a);
	}
	for(int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof(vis));
		ans=0;
		cin>>c;
		for(int i=1;i<=n;i++)
		{
			if(vis[i]==0&&i!=c)
			{
				vis[i]=1;
				ans++;
				dfs(i);
			}
		}
		cout<<ans-1<<endl;
	}
	return 0;
}

D Waiting in Line (30 分)

【解题思路】

很显然这是一道模拟题,按照题意用队列模拟即可。

这种题目没有什么要用到的算法,就是有一定的代码量,且细节较多,代码当中做了注释。

如果正式考试最后一题考这种类型其实也挺好,静下心来一步步分析,遇到困难总是有办法解决的。

因为PAT考试是可以实时看到得分的,哪怕一开始没有拿到满分,也可以通过不断修改来提高,三个小时的时间相对而言也比较充裕。希望能够通过这段时间的练习,取得一个不错的成绩。

【满分代码】

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int n,m,k,q,a,t[1005],ans[1005];
struct node
{
	int poptime,endtime;//第一个人出队时间,最后一个人结束时间 
	queue<int> que;//队伍 
}w[25];//窗口 
int main()
{
	int index=0;//当前处理的客户编号 
	cin>>n>>m>>k>>q;
	for(int i=0;i<k;i++)
		cin>>t[i];
	for(int i=0;i<n;i++)
		w[i].poptime=w[i].endtime=0;//初始化时间 
	for(int i=0;i<min(n*m,k);i++)
	{
		w[index%n].que.push(index);
		w[index%n].endtime+=t[index];
		if(index<n)
			w[index].poptime=t[index];
		ans[index]=w[index%n].endtime;
		index++;
	}
	for(;index<k;index++)
	{
		int temp=0,mint=1999999999;
		for(int i=0;i<n;i++)
		{
			if(w[i].poptime<mint)
			{
				mint=w[i].poptime;
				temp=i;
			}
		}//找到最快空出位置的窗口排队,如果同时空出则默认在前的窗口优先 
		w[temp].que.pop();
		w[temp].que.push(index);
		w[temp].poptime+=t[w[temp].que.front()];
		w[temp].endtime+=t[index];
		ans[index]=w[temp].endtime;
	}
	for(int i=0;i<q;i++)
	{
		cin>>a;
		a--;//下标从0开始 
		if(ans[a]-t[a]<540)
			printf("%02d:%02d\n",ans[a]/60+8,ans[a]%60);//注意时间加上8点 
		else
			printf("Sorry\n");
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

球王武磊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值