2023春PAT乙级记录

最后一分钟把题目复制到编译器里,再打开一看乱码了,算了算了将就看看吧 

B-1 常有理的立方组

本题就请你编写程序,为任一给定的正有理数 m/n 找出对应的最小的常有理的立方组。

输入格式:
输入给出三个正整数 m、n 和 N 

输出格式:
在一行中依次输出求得的 a、b、c、d 的值,其间以 1 空格分隔,行首尾不得有多余空格。

若在给定范围内没有解,则在一行中输出 No Solution in [1, Nmax] for m/n.

输入样例 1:
5 3 10
输出样例 1:
7 8 1 8
输入样例 2:
25 89 20
输出样例 2:
No Solution in [1, 20] for 25/89.
代码长度限制
16 KB
时间限制
400 ms
内存限制

64 MB

解题思路:这道题一上来就给我干懵了,一开始题目都没看懂,好在是看了几遍理解了,给你m和n,要你在【1,nmax】里找abcd四个数,满足那个式子,因为是第一题,直接四层嵌套循环即可,但因为是两个分数比较相等与否,例如x1/y1和x2/y2,不能直接判断那个除式,需要转换成判断x1*y2==x2*y1,看上去这道题难住了好多人,到最后看了一眼排名,做出这道题的人并不算很多。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int m,n,nmax;
	cin>>m>>n>>nmax;
	int flag=0;
	for(int a=1;a<=nmax;a++)
	{
		if(flag==1)
		   break;
		for(int b=a;b<=nmax;b++)
		{
			if(flag==1)
			   break;
			for(int c=1;c<=nmax;c++)
			{
				if(flag==1)
				   break;
				for(int d=c;d<=nmax;d++)
				{
                    int x1 = a*a*a + b*b*b;
                    int x2 = c*c*c + d*d*d;
                    if(m*x2==x1*n)               //转换成乘法判断
                    {
                    	flag=1;
                    	cout<<a<<" "<<b<<" "<<c<<" "<<d;
                    	break;
					}
				}
			}
		}
	}
	if(flag==0)
	   printf("No Solution in [1, %d] for %d/%d.",nmax,m,n);
} 

 

B-2 滑动窗口

给定一个由字符组成的长方形块,要请你用一个高度为 h、宽度为 w 的窗口从左向右滑动 R 个字符后,再从上到下滑过 D 个字符,然后截取一个子块。

输入格式:
输入第一行给出两个不超过 100 的正整数 n 和 m,依次为字符块的行数和列数。随后 n 行,每行给出 m 个英文字母。

在给出了原始字符块以后,下一行依次给出窗口的高度 h、宽度 w、向右滑动的距离 R 和向下滑动的距离 D。数字均为不超过 100 的正整数,以空格分隔。

输出格式:
输出滑动窗口截取的内容。窗口截取到空的地方,用 * 填充。

输入样例 1:
4 17
ThisIsATestString
xyzIILovePTAdefgh
ijkoProgramminggg
ThisIsATestString
2 8 4 1
输出样例 1:
ILovePTA
Programm
输入样例 2:
4 17
ThisIsATestString
xyzIILovePTAdefgh
ijkoProgramminggg
ThisIsATestString
2 8 6 3
输出样例 2:
ATestStr
********
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

解题思路:第一题一开始没想到,先做的这题,这题还算是比较容易的,找到滑动过后的行起始下标和列起始下标即可 ,注意有可能会行列下标可能超出范围,此时输出*

 

#include<bits/stdc++.h>
using namespace std;
char s[101][101];
int main()
{
	int n,m;
	cin>>n>>m;
	getchar();
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%c",&s[i][j]);
		}
		getchar();                
	}
	int h,w,r,d;
	scanf("%d %d %d %d",&h,&w,&r,&d);
	for(int i=d;i<d+h;i++)               //起始行和末尾行
	{ 
		for(int j=r;j<r+w;j++)            //起始列和末尾列
		{
			if(i<n&&j<m)
			  printf("%c",s[i][j]);
			else
			  printf("*");
		}
		cout<<endl;
	}
}

B-3 ChatGPT
分数 20
ChatGPT(全名:Chat Generative Pre-trained Transformer)近期成为网络讨论的热点话题之一。本题就请你根据某社交网络中发帖的情况,统计每个人帖子中含有 ChatGPT(不区分大小写)的数量(简称“含茶量”),找出最热衷于讨论这个话题的人,即含茶量最高的人。

输入格式:
输入在第一行中给出正整数:N(≤1000),为参加统计的帖子数量。

随后给出 N 条帖子的信息,每条格式为:第一行给出发帖人 ID,是一个长度为 4 位的非空数字串;第二行给出非空的帖子的内容,由不超过 140 个英文字母、数字、空格、标点(只包括 ?、, 和 .)组成,以回车结束(回车不算在 140 字内)。

输出格式:
在一行中输出含茶量最高的 ID,及其含茶量。数字间以 1 个空格分隔,行首尾不得有多余空格。

题目保证输出唯一。

输入样例:
4
1010
I am not interested in ChatGPT.
2333
I am gonna talk about chatgpt, and Chatgpt, and CHATGPT
2333
they are all ChatGPT
0002
So what are you talking about, chatPPT?
输出样例:
2333 4
代码长度限制
16 KB
Java (javac)
时间限制
600 ms
内存限制
256 MB
其他编译器
时间限制
400 ms
内存限制
64 MB

解题思路:这道题也不难,找到chatgpt在每个字符串出现的次数即可,注意有可能有同一个人发了好几条帖子(一开始没看出来,找半天我就说这个人说的话中哪来4个chatgpt,明明就3个,后来再一看,hjh,下一个帖子也是你小子发的)  

 

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n; 
	int count[10005]={0};      //出现次数 
	for(int i=0;i<n;i++)
	{
	    int id;
	    cin>>id;
		getchar();
		string s;
		getline(cin,s);
		int len = s.length();
		for(int j=0;j<len;j++)  
		{
			s[j]=tolower(s[j]);
		}
		for(int j=0;j<len;j++)           //计算chatgpt出现次数
		{
			if(s[j]=='c'&&s[j+1]=='h'&&s[j+2]=='a'&&s[j+3]=='t'&&
			s[j+4]=='g'&&s[j+5]=='p'&&s[j+6]=='t')
			{
				count[id]++;        //这个ID说的chatgpt次数+1
				j = j+6;
			}
		}
	}
	int max=-1,maxpos;
	for(int i=0;i<10000;i++)
	{
		if(max<=count[i])
		{
			max=count[i];
			maxpos=i;
		}
	}
	printf("%04d %d",maxpos,max);
}

B-4 打掉平方素
分数 20
“打掉平方素”是把平方数和素数逐个筛除的游戏。

游戏最开始有 N 位玩家,从左到右坐在编号从 1 到 N 的座位上。游戏开始后,首先坐在编号为平方数(例如 1、4、9、16、……)座位上的玩家出局,剩下的玩家向左边移动,使得任何两个玩家间没有空座位留下。大家坐定后,下一轮请坐在编号为素数座位上的玩家出局,剩下的玩家再次向左边移动。如此反复,交替筛除平方数和素数座位上的玩家,直到最后只有一个赢家剩下来。本题就请你给出这个赢家最初的座位号。

输入格式:
输入给出一个正整数 N(≤10 
5
 )。

输出格式:
在一行中输出这个游戏赢家最初的座位号。

输入样例:
10
输出样例:
6
样例解释:
第 1 轮:坐在 1、4、9 号座位的玩家离开。坐在编号为 1 到 7 的座位上的玩家们的初始座位号依次为 2、3、5、6、7、8、10。

第 2 轮:坐在 2、3、5、7 号座位的玩家离开。坐在编号为 1 到 3 的座位上的玩家们的初始座位号依次为 2、6、8。

第 3 轮:坐在 1 号座位的玩家离开。坐在编号为 1 到 2 的座位上的玩家们的初始座位号依次为 6、8。

第 4 轮:坐在 2 号座位的玩家离开。最后赢家的初始座位号为 6。

代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

解题思路:这道题花了我挺多时间的,题目中两个游戏判断的是座位的编号,一开始我写成了判断坐在座位上的数,一直报运行超时,心态差点都不好了,好在后来看出来了,还是要好好看题目! 

 

#include<bits/stdc++.h>
using namespace std;
int isPrime(int n)   //判断素数 
{
	if(n<2)
	   return 0;
	for(int i=2;i<=sqrt(n);i++)
	{
		if(n%i==0)
		  return 0;
	}
	return 1;
}
int isPingfang(int n)   //判断平方 
{
    int x = sqrt(n);
	if(x*x==n)
	    return 1;
	return 0;	
} 
int main()
{
	int n;
	scanf("%d",&n);
	int t = 1;   //1:平方 2:素数
	int flag[100005]={0};
	int number[100005];
	int round=1;
	while(1)
	{
		int count =0;
	    for(int i=1;i<=n;i++)
		{
		    if(flag[i]==1)
			   count++;	
		}	
		if(count==n-1)  //仅剩一个玩家 
		{
			for(int i=1;i<=n;i++)
		    {
		        if(flag[i]==0)
			       printf("%d",i);
		    }	
			 break;
		}
		else
		{
			int index=1;
			int j = 1;
			while(j<=n-count)  //重新排位置 
			{
				if(flag[index]==0)
				{
					number[j]=index;
					index++;
					j++;
				}
				else
				   index++;
			}
			if(t==1)  //平方数out 
			{
				for(int j=1;j<=n-count;j++)
				{
					if(isPingfang(j)==1)
					   flag[number[j]]=1;
				}
			}
			else           //素数out 
			{
				for(int j=1;j<=n-count;j++)
				{
					if(isPrime(j)==1)
					   flag[number[j]]=1;
				}
			
			}
			t=-t;
		}
	} 

}

B-5 LRU-K 缓存
分数 25
LRU 全称为 Least Recently Used,即“最近最少使用”。LRU 缓存机制是指,当缓存满了,而缓存区外面的一个新数据被调用的时候,将缓存中最近最少使用(即最长时间没有被使用过)的数据清除,为新数据开辟出空间。

LRU-K 是 LRU 算法的变种,K 代表最近使用的次数,LRU 可以认为是 LRU-1。不同于 LRU 算法的是,LRU-K 算法需要维护两套队列(历史访问队列,缓存队列)。当历史访问队列中的数据被命中 K 次后,数据才会移动至缓存队列中。

例如:假设所有队列长度为 5,初始内存中没有数据。使用 LRU-2 算法,数据访问顺序为:9,5,6,7,8,3,8,9,5,9,8,3,4,7,5,6。则历史访问队列和缓存队列的变化如下表所示:

访问元素    历史访问队列    缓存队列
9,5,6,7,8    9,5,6,7,8    空
3    5,6,7,8,3    空
8    5,6,7,3    8
9    5,6,7,3,9    8
5    6,7,3,9    8,5
9    6,7,3    8,5,9
8    6,7,3    5,9,8
3    6,7    5,9,8,3
4    6,7,4    5,9,8,3
7    6,4    5,9,8,3,7
5    6,4    9,8,3,7,5
6    4    8,3,7,5,6
你的任务就是实现这种 LRU-K 缓存机制。

输入格式:
输入第一行给出 3 个正整数:K(1<K≤5)、N (≤10 
4
 ) 和 M (≤10 
5
 ),分别为规定的缓存命中次数、队列的大小(假设历史访问队列和缓存队列的大小一致)和被调用的数据的数量。随后一行给出 M 个被调用的数据的编号。编号为区间 [1,2×10 
4
 ] 内的一个整数。一行中的数字以空格分隔。

输出格式:
在第一行中输出历史访问队列中数据的编号。第二行输出缓存队列中数据的编号。顺序为队头至队尾。数据间以 1 个空格分隔,行首尾不得有多余空格。如果队列为空则输出 - 表示空行。

输入样例 1:
2 5 17
9 5 6 7 8 3 8 9 5 9 8 3 4 7 5 6 9
输出样例 1:
4 9
8 3 7 5 6
输入样例 2:
3 5 10
9 5 6 7 8 3 8 9 5 9
输出样例 2:
7 3 8 5 9
-
代码长度限制
16 KB
Java (javac)
时间限制
900 ms
内存限制
256 MB
其他编译器
时间限制
200 ms
内存限制
64 MB                          

解题思路:没做出来,我最后交卷的时候,看了一眼第一名这道题也只有17分,看来挺难的吼,我不会也合理。照着题目实例模拟了几遍懂了大概的处理流程,因为不会stl的queue容器(早忘了,也可能从没有会过),我一开始用两个数组来模拟这两个队列,果不其然,无情的运行超时,但给了1分;后来我换成用2个字符串模拟两个队列,题目实例第二个跑对了,一提交,3分,罢了,就这样吧。 

 

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值