2019寒假集训入学测试订正(1)

博客回顾了寒假集训的入学测试,重点讨论了优先队列的应用,通过实例介绍了如何使用优先队列解决数字集合操作问题。同时,提到了矩阵计算最大0区域面积和汽车限行日期判断的模拟题,以及一道涉及单位转换的人工智能题目,强调了模拟题的细节处理重要性。

集训报道的那一天,有考试啊。在学校的同学们都是从上午开始比赛。都打了七八个小时了。我下午三点多到机房,乍一看居然发现题目不会。然后死磕了几个小时,后来居然可以加个四十多的rating。

  • T1 优先队列

description

给定一个初始数字集合,

对其做如下两种操作:

  1. 添加一个新的数字
  2. 将集合中当前最小的数字取出(输出并删除),如果最小的数字有多个,只取出其中一个。
当初我看到的时候……

我看到优先队列的时候,觉得就是我听过他,他不认识我,也就是……

我:优先队列大哥,久仰大名
优先队列:您是哪位?

在这里插入图片描述

终于,我懂了(我不确定我到底会不会),我认识他了。

优先队列(priority queue)
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。
————摘自百度

现在嘛

但是手写我还是不会。我是用STL内置的大根堆来写的,优先队列直接可以得出序列最值,此题虽然数的变化大,但是只要求一个最小值,适合优先队列。

在这里插入图片描述

过了啊。

代码:
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[10010];
priority_queue<int> q;
int head=1,tail=1;
int main()
{
	freopen("priority.in","r",stdin);
	freopen("priority.out","w",stdout);
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		q.push(-x);//放入堆(优先队列)
	}
	int t;
	cin>>t;
	for (int i=1;i<=t;i++)
	{
		string s;
		cin>>s;
		if (s=="Erase")
		{
			cout<<-q.top()<<endl;//输出堆顶
			q.pop();//弹出堆首
		}
		else
		{
			int x;
			cin>>x;
			q.push(-x);//放入堆
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
  • T2

description

计算保护林中所能用来盖房子的矩形空地的最大面积,即输入一个0 1 矩阵,计算最大的全部为0 的矩阵的面积。

solution?? maybe

预处理出第i行到第j个的时候共有几个连续的0.当处理了行后,再去找列,每一个矩阵的面积=len列*min{当前矩阵的每行最小的连续的0的个数}

#include<bits/stdc++.h>
using namespace std;
int n,m;
int w[30][30];
int hg[30][30],ln[30][30];
int ans=-1;
int main()
{
	freopen("forest.in","r",stdin);
	freopen("forest.out","w",stdout);
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	    cin>>w[i][j];
	// 预处理行
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	  {
	  	if (w[i][j]==1)
	  	{
	  		hg[i][j]=0;
	  		ln[i][j]=0;
		}
		else
		{
			hg[i][j]=hg[i][j-1]+1;
			ln[i][j]=ln[i-1][j]+1;
		}
	  }
	 //处理列,同时计算
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	  {
	  	int Min=hg[i][j];
	  	for (int o=1;o<=ln[i][j];o++)
	  	{
//	  		int x;
	  		Min=min(hg[i-o+1][j],Min);
	  		ans=max(ans,Min*o);
		}
	  }
	cout<<ans<<endl;
	fclose(stdin);
	fclose(stdout);
}

在这里插入图片描述

  • T3汽车限行

description

为了缓解交通压力、减少空气污染,B市市政府决定在工作日(周一至周五)对机动车进行限行,每辆机动车每周将有一个工作日不能出行,但周末不限行。假设该政策从2000年1月1日起开始执行。限行安排为:

  1. 尾号为 1 和 6:周一限行
  2. 尾号为 2 和 7:周二限行
  3. 尾号为 3 和 8:周三限行
  4. 尾号为 4 和 9:周四限行
  5. 尾号为 5、​0​ 和字母:周五限行

已知 2000 年 11 月11 日为周六,现在给出一些日期和车牌号,求问该机动车在该天是否限行。

solution

这一题呢,我是先预处理出数据范围内每一年每个月每天分别是星期几。由于这题的数据不大,年份最多是2020年。
然后再输入年月日,分别判断是否会被限行。

想当初,这道题浪费我大把青春的。模拟太恶心!!!
代码有点壮观……
#include<bits/stdc++.h>
using namespace std;
int n;
string s,s1;
int a[25][13][32];
int aa[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
	freopen("car.in","r",stdin);
	freopen("car.out","w",stdout);
	cin>>n;
	int p=6;
	for (int i=2000;i<=2021;i++)
	  for (int j=1;j<=12;j++)
	  {
	  	if (j==2)
	  	{
	  		if (i%4==0)
	  		{
	  			for (int k=1;k<=29;k++)
	  			{
	  				a[i%100][j][k]=p;
	  				p++;
	  				if (p>7) p=1;
				}
			}
			else 
			  for (int k=1;k<=28;k++)
			  {
			  	a[i%100][j][k]=p;
			  	p++;
			  	if (p>7) p=1;
			  }
		}
		else
		{
			for (int k=1;k<=aa[j];k++)
			{
				a[i%100][j][k]=p;
				p++;
				if (p>7) p=1;
			}
		}
	  }
	for (int t=1;t<=n;t++)
	{
		bool pp=false;
		cin>>s>>s1;
		int y=0,m=0,d=0;
		for (int i=0;i<4;i++)
		  y=10*y+int(s[i]-'0');
		for (int i=5;i<=6;i++)
		  m=10*m+int(s[i]-'0');
		for (int i=8;i<=9;i++)
		  d=10*d+int(s[i]-'0');
		if (a[y%100][m][d]==1&&(s1[4]=='1'||s1[4]=='6'))
		  	pp=true;
		if (a[y%100][m][d]==2&&(s1[4]=='2'||s1[4]=='7'))
		  	pp=true;
		if (a[y%100][m][d]==3&&(s1[4]=='3'||s1[4]=='8'))
		  	pp=true;
		if (a[y%100][m][d]==4&&(s1[4]=='4'||s1[4]=='9'))
		  	pp=true;
		if (a[y%100][m][d]==5&&(s1[4]=='5'||s1[4]=='0'||s1[4]>='a'&&s1[4]<='z'||s1[4]>='A'&&s1[4]<='Z'))
		  	pp=true;
		if (pp)
		  cout<<"yes";
		 else cout<<"no";		
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
  • T4人工智能

description

根据公式 P=UI输入P,U,I中的任意两个,输出剩下一个变量。更恶心的是这题每个变量都有多个,但是输出的答案必须只按一种来输出。
输入格式
输入共 T+1T+1 行。

第 11 行,一个正整数 TT;

第 2∼T+12∼T+1 行,每行以以下形式给给出两个已知变量的值:

{变量名}={实数}{单位} {变量名}={实数}{单位}
对于单位,给出单位表:
在这里插入图片描述

这一题就是模拟,只要单位转化对,输出保留小数,格式正确就好了。然鹅,我还是做了好久。这些模拟题都是抠细节的东西。

代码
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int n;
int main()
{
	freopen("ai.in","r",stdin);
	freopen("ai.out","w",stdout);
	cin>>n;
	for (int t=1;t<=n;t++)
	{
		cin>>s1>>s2;
		
		double a=0,b=1.0;
		int l;
		for (l=2;s1[l]!='.';l++)
		  a=a*10+double(s1[l]-48);
		l++;
		for (int j=l;s1[j]>='0'&&s1[j]<='9';j++)
		{
			b/=10;
			a+=double(s1[j]-48)*b;
		}
		double aa=a;
		a=0,b=1.0;
		for (l=2;s2[l]!='.';l++)
		  a=a*10+double(s2[l]-48);
		l++;
		for (int j=l;s2[j]>='0'&&s2[j]<='9';j++)
		{
			b/=10;
			a+=double(s2[j]-48)*b;
		int len1=s1.size()-2,len2=s2.size()-2;
		if (s1[len1]>'9')
		{
			if (s1[len1]=='m') aa/=1000;
			if (s1[len1]=='k') aa*=1000;
			if (s1[len1]=='M') aa*=1000000;
		}
		if (s2[len2]>'9')
		{
			if (s2[len2]=='m') a/=1000;
			if (s2[len2]=='k') a*=1000;
			if (s2[len2]=='M') a*=1000000;
		}
		
		cout<<"Problem #"<<t<<endl;
		
		if (s1[0]=='U'&&s2[0]=='I'||s1[0]=='I'&&s2[0]=='U')
		{
			cout<<"P=";
			cout<<setiosflags(ios::fixed)<<setprecision(2);
    		cout<<a*aa;
    		cout<<"W"<<endl;
		}
		if (s1[0]=='P'&&s2[0]=='U')
		{
			cout<<"I=";
			cout<<setiosflags(ios::fixed)<<setprecision(2);
		    cout<<aa/a;
			cout<<"A"<<endl;
		}
		if (s1[0]=='U'&&s2[0]=='P')
		{
			cout<<"I=";
			cout<<setiosflags(ios::fixed)<<setprecision(2);
		    cout<<a/aa;
			cout<<"A"<<endl;
		}
		if (s1[0]=='P'&&s2[0]=='I')
		{
			cout<<"U=";
			cout<<setiosflags(ios::fixed)<<setprecision(2);
		    cout<<aa/a;
			cout<<"V"<<endl;
		}
		if (s1[0]=='I'&&s2[0]=='P')
		{
			cout<<"U=";
			cout<<setiosflags(ios::fixed)<<setprecision(2);
		    cout<<a/aa;
			cout<<"V"<<endl;
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值