AtCoder Beginner Contest 289 题解

32 篇文章 0 订阅
31 篇文章 0 订阅

D - Step Up Robot

大意:
格子阶梯,给定一步可以走的步数选择,不能后退,问从0开始能否走到n

思路:
dfs+记忆化

code

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define endl '\n'
const ll N=2e5+10;
ll n,m;
ll a,o;
ll mas[N];
ll num[N];
ll vis[N];
ll ans[N];
bool dfs(ll id)
{
	if(ans[id]!=-1) return ans[id]; 
	if(vis[id]) return 0;
	if(id>o) return 0;
	if(id==o) return 1;
	for(int i=1;i<=n;++i)
	{
		if(dfs(id+mas[i])) return ans[id]=1;
	}
	return ans[id]=0;
}
void solve()
{
	cin>>n;
	memset(ans,-1,sizeof ans);
	for(int i=1;i<=n;++i) cin>>mas[i];
	cin>>m;
	for(int i=1;i<=m;++i)
	{
		cin>>a;
		vis[a]=1;
	}
	cin>>o;
	cout<<(dfs(0)?"Yes":"No")<<endl;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	//ll t;cin>>t;while(t--)
	solve();
	return 0;
}

E - Swap Places

大意:
一张简单图,每一个点有一个颜色(1或0),两个点从分别从1和n出发,同时走下一步,且两者下一步的颜色必须不同,问能否实现分别到达n和1.如果可以,求最小步数

思路:
因为点数和边数都不多,我们可以直接记录两个点的中间状态,然后bfs一下就可以了

初始状态是(1,n),最终状态是(n,1)

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define mk make_pair
const ll N=2010;
const ll inf=1e9;
ll n,m;
vector<ll> vt[N];
ll mp[N][N];
ll col[N];
void bfs()
{
	queue<pair<ll,ll>> q;
	q.push(mk(1,n));
	mp[1][n]=0;
	while(!q.empty())
	{
		ll x=q.front().first;
		ll y=q.front().second;
		q.pop();
		for(auto xx:vt[x])
		{
			for(auto yy:vt[y])
			{
				if(mp[xx][yy]!=inf) continue;
				if(col[xx]==col[yy]) continue;
				mp[xx][yy]=mp[x][y]+1;
				q.push(mk(xx,yy));
				if(mp[n][1]!=inf) return;
			}
		}
		
		
	}
		
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>col[i],vt[i].clear();
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j) mp[i][j]=inf;
	}
	for(int i=1;i<=m;++i)
	{
		ll a,b;
		cin>>a>>b;
		vt[a].push_back(b);
		vt[b].push_back(a);
	}
	bfs();
	cout<<(mp[n][1]!=inf?mp[n][1]:-1)<<endl;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	ll t;cin>>t;while(t--)
	solve();
	return 0;
}

F - Teleporter Takahashi

大意:
二维平面,给定起点A和终点B,要求从A走到B。

规则如下,每次在一个选定区域内选择一个坐标均为整数的点C,移动到关于点C对称的点。

如果能实现,输出每次操作选定的对称点

选定区域:R:={(x,y)∣a−0.5≤x≤b+0.5,c−0.5≤y≤d+0.5}

思路:

为什么我会想到投影的方向去。。。)

不难发现,如果我们能够实现每次只改变横坐标/纵坐标的话,是可以贪心解决该问题的。更进一步,在不改变横坐标的情况下,如果连续两次选择的点的纵坐标相差=1,那么最后的实际效果是纵坐标变化=2,这是改变的最小差值。所以一个能实现的前提就是:起终点的坐标差值为偶数

接着,每次改变2的话,贪心一下就好了。因为如果我们只改变纵坐标的话,第一次选(a,c),第二次选(a,c+1),可以发现横坐标会回到原位

但是还有a=b或者c=d的情况(wa烂了)

自行体会吧,有些坑还是得自己去踩

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define mk make_pair
const ll N=2010;
const ll inf=1e9;
ll n,m;
ll a,b,c,d;
ll sx,sy,tx,ty;
bool f1,f2;
void solve()
{
	cin>>sx>>sy>>tx>>ty;
	cin>>a>>b>>c>>d;
	if(abs(sx-tx)%2||abs(sy-ty)%2)
	{
		cout<<"No"<<endl;
		return;
	}
	if(a==b&&c==d)
	{
		if((sx+tx)==2*a&&(sy+ty)==2*c) 
		{
			cout<<"Yes"<<endl;
			cout<<a<<' '<<c<<endl;
			return;
		}
		else cout<<"No"<<endl;
		return;
	}
	if(a==b&&sx!=tx)
	{
		if((sx+tx)!=2*a)
		{
			cout<<"No"<<endl;
			return;
		}
		f1=1;
	}
	if(c==d&&sy!=ty)
	{
		if((sy+ty)!=2*c)
		{
			cout<<"No"<<endl;
			return;
		}
		f2=1;
	}
	cout<<"Yes"<<endl;
	ll det1=sx-tx;
	ll det2=sy-ty;
	if(f1)
	{
		det1=0;
		cout<<a<<' '<<c<<endl;
		det2=2*c-sy-ty;
	}
	if(f2)
	{
		det2=0;
		cout<<a<<" "<<c<<endl;
		det1=2*a-sx-tx;
	}
	while(det1>0)
	{
		cout<<a+1<<" "<<c<<endl<<a<<" "<<c<<endl;
		det1-=2;
	}
	while(det1<0)
	{
		cout<<a<<" "<<c<<endl<<a+1<<' '<<c<<endl;
		det1+=2;
	}
	while(det2>0)
	{
		cout<<a<<' '<<c+1<<endl<<a<<' '<<c<<endl;
		det2-=2;
	}
	while(det2<0)
	{
		cout<<a<<' '<<c<<endl<<a<<' '<<c+1<<endl;
		det2+=2;
	}
	
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	//ll t;cin>>t;while(t--)
	solve();
	return 0;
}

G

详见我的另一篇博客

Ex

不会

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值