【天梯赛补题】

175对我这种蒟蒻好难,,,

L1-6剪切粘贴

题目详情 - L1-094 剪切粘贴 (pintia.cn)

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
string s;
int k;
signed main()
{
	cin>>s>>k;
	while(k--)
	{
		int l,r;
		string a,b;
		cin>>l>>r>>a>>b;
		string jq=s.substr(l-1,r-l+1);//剪切板 
		string pre=s.substr(0,l-1);//前端 
		string end=s.substr(r);//后端 
		string tmp=a+b;//要找的子串 
		s=pre+end;
		int flag=0; 
		for(int i=0;i<s.size();i++)
		{
			if(tmp==s.substr(i,tmp.size()))
			{
				flag=1;
				s.insert(i+a.size(),jq);
				break;
			}
		}
		if(!flag) s+=jq;
	}
		cout<<s;
	
	return 0;
}

这题要静下心来模拟~

然后仔细读题!!

L1-7分寝室

题目详情 - L1-095 分寝室 (pintia.cn)

这题感觉像小学数学应用题。

女生n0,男生n1,一共n间寝室。

我们直接暴力,让i作为女寝个数,自然男寝个数就是(n-i)

要求每个女寝人数相同,男寝人数相同

只要n0能整除女寝个数(男寝同理。)就可以作为备选答案。

然后找出差最小的答案就可以了。

(仔细看题,n0和n1都是正整数,也就男女都有人,所以男女寝室至少都有一个,所以i从2开始走到n-1)

有个点不能过。        (考场上看了挺久都不能a,而且就一分没细究。

然后看了佬。 

 

AC代码: 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,n0,n1;//n 间寝室。等待分配的学生中,有女生 n0,n1男生 

int ans1,ans2;
int cha=1e8;
int flag;
signed main()
{
	cin>>n0>>n1>>n; 
	
	for(int i=2;i<=n-1;i++)
	{
		int x=n-i;
		if(n0%i==0&&n1%x==0)
		{
			int a=n0/i;
			int b=n1/x;//代表几人间 
			if(a==1||b==1) continue;//加上判断是不是一人间
			int c=a-b;
			if(abs(c)<cha)
			{
				cha=abs(c);
				flag=1;
				ans1=i;
				ans2=x;
			}
		}
	}
	if(flag==0) cout<<"No Solution";
	else cout<<ans1<<" "<<ans2;

	return 0;
}

L2-1堆宝塔

题目详情 - L2-045 堆宝塔 (pintia.cn)

感觉是模拟+栈,

考场写的时候第一遍只有15,原因是所有数都看过一遍之后,柱子上剩余的圈圈也可以当成一个塔。只要在最后加个判断就好了

加了判断之后还是只有16,报错?段错误

 

问了佬。

要记住:

栈采用  pop  或者  top操作 之前一定要  判空!!

然后判断语句里面一定也是要先判空再操作

要   if(!b.empty()     &&      b.top()>num)

先判空!!!

然后就可以AC咯

#include<bits/stdc++.h>
using namespace std;
stack<int> a;
stack<int> b;
int n;
int h=0;
int cnt;
signed main()
{
	cin>>n;
	while(n--)
	{
		int num;
		cin>>num;
		if(a.empty())
		{
			a.push(num);
			continue;
		}
		if(num<a.top())
		{
			a.push(num);
			continue;
		}else if(b.empty()||b.top()<num){
			b.push(num);
			continue;
		}else{
			cnt++;
			if(a.size()>h)
			{
				h=a.size();
			}
			while(!a.empty())
			{
				a.pop();
			}
			while(!b.empty()&&b.top()>num)
			{
				a.push(b.top());
				b.pop();
			}
			a.push(num);
		}
	}
	if(!a.empty())
    {
        cnt++;
        if(a.size()>h)
		{
			h=a.size();
		}
    }
    if(!b.empty())
    {
        cnt++;
        if(b.size()>h)
		{
			h=b.size();
		}
    }
	cout<<cnt<<" "<<h;
	return 0;
}

L2-2 天梯赛的赛场安排

题目详情 - L2-046 天梯赛的赛场安排 (pintia.cn)

赛场骗了个15分,想到了优先队列但没用过,就数组模拟骗分haha~

刷微博才发现之前题目都理解错了2023 年团体程序设计天梯赛出题笔记及解题报告 (qq.com)

昨天写了很久都不能A,是因为昨天是在输入阶段就把数据压入了队列,但是仔细看题会发现不对劲!!

这里的排座顺序会对结果产生很大的影响!!!

我们这里的思路是,前面的输出很简单,难点是最后一行的输出,因此前面我们采取边输入边输出的形式。

同时对于每一个学校,刚好能做考场的人对排座没有什么影响,我们让ans+cap/c,并且保存余数,放进数组。

对数组进行排序。

我们从大到小进行讨论,(后面就比较简单了;

队列不空且堆顶能容纳当前人数,就塞人进去,

否则再开一个考场!

终于A了,蒟蒻太不容易了!!

AC代码

#include<bits/stdc++.h>
const int N=1e8;
using namespace std;
int n,c;//参赛学校数量和每个赛场的规定容量
int a[N];
int ans;
priority_queue<int> pq;//记录剩余容量 
bool cmp(int c,int d)
{
	return c>d;
}
signed main()
{
	cin>>n>>c;
	int j=1;
	for(int i=1;i<=n;i++)
	{
		string name;
		int cap;
		cin>>name>>cap;
		int cnt=cap/c;
		ans+=cnt;
		if(cap%c!=0)
		{
			cnt++;
			a[j++]=cap%c;
		}
		cout<<name<<" "<<cnt<<endl; 
	}//到最后数组里一共有j个数 
	sort(a+1,a+j,cmp);
	for(int i=1;i<j;i++)
	{
		if(!pq.empty()&&pq.top()>=a[i])
		{
			if(pq.top()==a[i])//刚好容纳 
			{
				pq.pop(); 
			}else{
				int temp=pq.top();
				pq.pop();
				pq.push(temp-a[i]);
			} 
		}else{
			pq.push(c-a[i]);
			ans++;//新开一个考场 
		}
	}
	cout<<ans;
	return 0;
}

L2-3 锦标赛

题目详情 - L2-047 锦标赛 (pintia.cn)

(现在看发现好像直接输出no solution能骗分??

L2-4 寻宝图

题目详情 - L2-048 寻宝图 (pintia.cn)

思路就是把地图遍历一遍,如果找到不为0的元素就bfs把能走的都走一趟,同时用st数组记录一遍。能走几次就代表有几个岛屿。找宝藏就是在bfs里额外加一个判断。

就是细节容易出问题。

#include<bits/stdc++.h>
#define f first
#define s second
const int N=1e3;
using namespace std;
char p[N][N];
vector<vector<char>> g;
int n,m;
bool st[N][N];
typedef pair<int,int> PII;
PII q[N*N];
int hh=0;
int tt=-1;//尾插头删 
int dx[]={1,0,-1,0};//要注意这题是四联通 
int dy[]={0,-1,0,1};
int res,ans;
void bfs(int x,int y)
{
	bool flag=false; 
	hh=0;
	tt=-1;
	q[++tt]={x,y};//入队 
	if(g[x][y]>'1') flag=true;//记录宝藏 
	while(hh<=tt) 
	{
		PII t=q[hh++];//头删 
		for(int i=0;i<4;i++)//遍历四个方向 
		{
			int a=t.f+dx[i];
			int b=t.s+dy[i];
			if(a<1||b<1||a>n||b>m) continue;//越界 
			if(st[a][b]) continue;//走过就不走了 
			if(g[a][b]=='0') continue;//不走0 
			
			q[++tt]={a,b};//入队 
			st[a][b]=true;
			if(g[a][b]>'1') flag=true;
		}	
	} 
	if(flag) ans++;
	return;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>(p[i]+1);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			g[i][j]=p[i][j];
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(g[i][j]!='0'&&!st[i][j])//只要不是0且没有走过就能走 
			{
				res++;
				st[i][j]=true; 
				bfs(i,j);//把当前点能到达的都走 
			}
		} 
	}
	cout<<res<<" "<<ans;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值