2025寒假训练——天梯赛训练(1)

出生年

出生年------PTA

最开始想复杂了,以为是一个公式,于是开始硬算,后来发现很多人通过的都很快,觉得自己的思路有问题,想着跑一下纯暴力,结果通过了。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
void slove(){
	cin>>n>>m;
	int i;
	int a,b,c,d;
	for(i=n;i<=3500;i++){
		
		int x=1;
		a=i/1000;//处理四位数
		b=i/100%10;
		c=i/10%10;
		d=i%10;
		//cout<<a<<b<<c<<d<<endl;
		if(a!=b&&a!=c&&a!=d) x++;//分别确认每一位与其他位之间是否相同
		if(b!=c&&b!=d) x++;
		if(c!=d) x++;
		if(x==m){
			cout<<i-n<<' ';
            printf("%04d\n",i);//不足四位的情况前面要填0,且零也算一个数字
			//cout<<11<<endl;
			break;
		}
	}
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}

九宫格输入法

九宫格输入法------PTA

选择用字符串数组来存储,将每一个键盘中对应的位数存为字符串,然后对于输入的字符串S只需要查找每一个字符串的第一位,就可以得知它所对应的已经存储好的字符串,然后知道字符串S的长度即可求出对应字符;这样交了一发,有的样例点不能通过。实际上还需要考虑一点,就是每一次输入的字符串长度有可能会超过存储长度,这种情况发生时,字符串S模一下对应字符串长度即可。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
string s[15];
void slove(){
	s[0]="0 ";
	s[1]="1,.?!";
	s[2]="2ABC";
	s[3]="3DEF";
	s[4]="4GHI";
	s[5]="5JKL";
	s[6]="6MNO";
	s[7]="7PQRS";
	s[8]="8TUV";
	s[9]="9WXYZ";
	string ss;
	while(cin>>ss){
		int x=ss[0]-'0';//知道对应的是哪一个字符串
		int i=ss.size()-1;//因为字符串下标从零开始
		string str=s[x];
        int cc=str.size();
        i%=cc;//防止输入字符串的长度大于存储字符串的长度
		cout<<str[i];
	}
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}

螺旋方阵

螺旋方阵------PTA

这道题在去年天梯赛练习的时候也写过,当使用了最笨的办法,一个一个输入的,今年就有所不同了,直接按照题意跑的循环,但是循环条件写错了,跑成了死循环,经过几次更改最终成功通过。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
int a[15][15];
void slove(){
	cin>>n;
	int x=0,y=0;
	int cnt=1;
	a[x][y]=1;
	while(cnt<n*n){//这个位置刚开始的时候有=,所以一直是死循环
		while(!a[x][y+1]&&y+1<n){
			a[x][++y]=++cnt;
		}
		while(!a[x+1][y]&&x+1<n){
			a[++x][y]=++cnt;
		}
		while(!a[x][y-1]&&y-1>=0){
			a[x][--y]=++cnt;
		}
		while(!a[x-1][y]&&x-1>=0){
			a[--x][y]=++cnt;
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			printf("%3d",a[i][j]);
            //cout<<i<<' '<<j<<endl;
		}
		printf("\n");
	}
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}

Windows消息队列

PTA-Windows消息队列

赛时采用的是纯暴力写法,这样只能通过部分样例。因为每次输入GET的时候就要进行一次排序,当数据n比较大且大多数输入都是GET的时候,就会发生超时。

赛时代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{
	string s;
	int x;
};
bool cmp(struct node a,struct node b){
	return a.x>b.x;
}
int l=0;
node nn[100005];
void slove(){
	string ss;
	cin>>ss;
	if(ss[0]=='P'){//就是将题目的意思直接模拟
		l++;
		cin>>nn[l].s>>nn[l].x;
	}
	else{
		if(l==0){
			cout<<"EMPTY QUEUE!"<<endl;
		}
		else{
			sort(nn+1,nn+l+1,cmp);
			cout<<nn[l].s<<endl;
			l--;
		}
	}
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
    	slove();
	}
}

改后:

原版代码费时的主要原因是每次排序需要消耗大量时间,而优选队列可以自动排序,这样就可以节省时间(比赛的时候想过用优先队列来写,但存储的时候既要存字符串,又要存整型数据,不知道队列该如何存储,赛后看到题解发现,其实只需要再多一个map就可以了)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
map<int,string> mp;//来存字符串及其对应的整型数据
priority_queue<int,vector<int>,greater<int> > q;//优先队列中只需要存整型数据,到时候直接在map中找到对应的字符串输出即可
void slove(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
        //cout<<s<<endl;
		if(s=="PUT"){
			string str;
			int m;
			cin>>str>>m;
			mp[m]=str;
			q.push(m);
		}
		else{
			if(q.empty()){
				cout<<"EMPTY QUEUE!"<<endl;
			}
			else{
				int a=q.top();
				q.pop();
				cout<<mp[a]<<endl;
				mp.erase(a);
			}
		}
	}
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}

用扑克牌计算24点

PTA-用扑克牌计算24点

在训练赛的时候知道它的符号总工会有64种情况,但是没有想明白括号的位置所以导致并没有很明确的存储思路,再加上前面的题写的太慢,导致留给这一道题的思考时间不是很多。

实际上括号的位置大致可以分为三种,第一种是每一个括号套两个数(a?b)?(c?d),第二种是前三个字母括号套括号的形式(a?(b?c))?d/((a?b)?c)?d,第三种是a?(b?(c?d))/a?((b?c)?d) 【?代表运算符】。题目中是说括号是控制优先级的,没说最终的结果要写最简的形式,所以为了统一格式,有些括号可以不进行删除。三个问号的位置每个问号都有四个选择,所一共有六十四种情况。

改后仍有一个样例点过不去,暂时还没找到问题。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
float suan(float a,float b,char c){
	switch(c){
		case '+':
			return a+b;
		case '-':
			return a-b;
		case '*':
			return a*b;
		case '/':
			return a/b;
	}
}
int temp(float a[] ,char c[]){
	float x=0,y=0,z=0;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			for(int k=0;k<4;k++){
				for(int l=0;l<4;l++){
					if(i!=j&&i!=k&&i!=l&&j!=k&&j!=l&&k!=l){
						x=suan(a[i],a[j],c[0]);
						y=suan(x,a[k],c[1]);
						z=suan(y,a[l],c[2]);
						if(z==24){
							printf("((%.0f%c%.0f)%c%.0f)%c%.0f", a[i], c[0], a[j], c[1], a[k], c[2], a[l]);
							return 1;
						}
						x=suan(a[j],a[k],c[1]);
						y=suan(a[i],x,c[0]);
						z=suan(y,a[l],c[2]);
						if(z==24){
							printf("(%.0f%c(%.0f%c%.0f))%c%.0f", a[i], c[0], a[j], c[1], a[k], c[2], a[l]);
							return 1;
						}
						x=suan(a[i],a[j],c[0]);
						y=suan(a[k],a[l],c[2]);
						z=suan(x,y,c[1]);
						if(z==24){
							printf("%.0f%c(%.0f%c(%.0f%c%.0f))", a[i], c[0], a[j], c[1], a[k], c[2], a[l]);
							return 1;
						}
						x=suan(a[j],a[k],c[1]);
						y=suan(x,a[l],c[2]);
						z=suan(a[i],y,c[0]);
						if(z==24){
							printf("%.0f%c((%.0f%c%.0f)%c%.0f)", a[i], c[0], a[j], c[1], a[k], c[2], a[l]);
							return 1;
						}
					}
				}
			}
		}
	}
	return 0;
}
void slove(){
	float num[4];
	for(int i=0;i<4;i++) cin>>num[i];
	string s="+-*/";
	char ch[65][5];
	int x=0;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			for(int k=0;k<4;k++){
				ch[x][0]=s[i];
				ch[x][1]=s[j];
				ch[x][2]=s[k];
				x++;
			}
		}
	}
	for(int i=0;i<64;i++){
		if(temp(num,ch[i])){
			return ;
		}
	}
	cout<<-1<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}

玩转二叉树

PTA-玩转二叉树

最主要的就是通过后序遍历和中序遍历来将这棵二叉树的形态确定下来,后序遍历是根左右,中序遍历是左根右,所以后序遍历的最后一个就一定是跟,然后在中序中寻找对应元素,前面的是左子树,后边的是右子树,然后依次递归;层次遍历有点不同,因为他要镜面的输出,所以遍历时同层要从右往左遍历。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{
	int data;
	struct node *l;
	struct node *r;
};
struct node *paixu(int s1[],int s2[],int k){//通过后序遍历和中序遍历确定出二叉树的形态
	int i,t;
	if(!k) return NULL;
	struct node *x=(struct node *)malloc(sizeof(struct node));
	t=s1[k-1];
	x->data=t;
	for(i=0;i<k;i++){
		if(s2[i]==t){
			break;
		}
	}
	x->l=paixu(s1+i,s2+i+1,k-i-1);
	return x;
}
void cengci(struct node *x){//因为要通过镜面反转在层次遍历输出,所以在遍历的时候,左右子树的遍历顺序要发生改变。
	struct node *s[35];
	int t=0,k=1;
	s[t]=x;
	while(t!=k){
		if(!t){
			printf("%d",s[t]->data);
		}
		else{
			printf(" %d",s[t]->data);
		}
		if(s[t]->l){
			s[k]=s[t]->l;
			k=(k+1)%31;
		}
		if(s[t]->r){
			s[k]=s[t]->r;
			k=(k+1)%31;
		}
		t=(t+1)%31;
	}
}
int n;
int s1[35],s2[35];
void slove(){
	cin>>s;
	for(int i=0;i<n;i++){
		cin>>s1[i];
	}
	for(int i=0;i<n;i++){
		cin>>s2[i];
	}
	struct node *x=paixu(s1,s2,n);
	cengci(x);
}

signed main() {
	ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
    	slove();
	}
}
相关推荐
半个番茄1 小时前
C 或 C++ 中用于表示常量的后缀:1ULL
c语言·开发语言·c++
玉带湖水位记录员2 小时前
状态模式——C++实现
开发语言·c++·状态模式
查理零世2 小时前
【算法】数论基础——约数个数定理、约数和定理 python
python·算法·数论
汉克老师4 小时前
GESP2024年3月认证C++六级( 第三部分编程题(1)游戏)
c++·学习·算法·游戏·动态规划·gesp6级
闻缺陷则喜何志丹4 小时前
【C++图论】2685. 统计完全连通分量的数量|1769
c++·算法·力扣·图论·数量·完全·连通分量
利刃大大4 小时前
【二叉树深搜】二叉搜索树中第K小的元素 && 二叉树的所有路径
c++·算法·二叉树·深度优先·dfs
CaptainDrake4 小时前
力扣 Hot 100 题解 (js版)更新ing
javascript·算法·leetcode
一缕叶4 小时前
洛谷P9420 [蓝桥杯 2023 国 B] 子 2023 / 双子数
算法·蓝桥杯
甜甜向上呀5 小时前
【数据结构】空间复杂度
数据结构·算法
Great Bruce Young5 小时前
GPS信号生成:C/A码序列生成【MATLAB实现】
算法·matlab·自动驾驶·信息与通信·信号处理