【CF #783 Div2】A-C

这篇博客探讨了三个算法问题:A. DirectionChange 中的最短路径问题,B. SocialDistance 中的椅子排列问题,以及C. MakeitIncreasing 中的数组操作以达到严格递增的问题。通过对每个问题的分析和代码实现,展示了如何利用排序、条件判断和数学计算来解决这些挑战。
摘要由CSDN通过智能技术生成

A. Direction Change

题目

分析

给一个n*m的矩阵,要从(1,1)处到达(n,m)处。每次不能向同一个方向移动两次,问最小的移动次数。

最小移动次数,所以每次都向下移动一次后向右移动一次,直到有一个方向碰壁。这个时候就只能蛇形走,然后判断奇偶,输出结果。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=2e5+10;
const ll N=32768;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		ll ans=0;	
		if(n==m||m==n+1||n==m+1)
		{
			ans=n+m-2;
			cout<<ans<<endl;
			continue;
		}
		if((n==1&&m!=2)||(n!=2&&m==1))
		{
			cout<<-1<<endl;
			continue;
		}
		int tt;
		if(n>m)
		{
			ans=m-1+m-2;
		//	cout<<ans<<" ";
			tt=n-m;
		//	cout<<tt<<" ";
			if(tt%2)
			{
				ans=ans+n-m+n-m;
			//	cout<<"1 ";
			//	cout<<ans<<endl;
			}
			else ans=ans+n-m+1+n-m;//,cout<<"11 "<<ans<<endl;
		}
		else {
			ans=n-1+n-2;
			tt=m-n;
			if(tt%2)
			{
				ans=ans+m-n+m-n;
			}
			else ans=ans+m-n+1+m-n;
		}
		cout<<ans<<endl;
	} 
	return 0;
}

B. Social Distance

题目

分析

n个人,m把椅子,a[i]表示第i个人左右有a[i]把椅子不能坐人,椅子围成圈,判断是否可以这样安排坐人。

先对数组a排序,两个人之间用后面的人需要的空椅子数安排(前面肯定小于等于后面,这样就可以直接满足前面的要求)第一个人和最后一个人之间的距离特殊判断。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=2e5+10;
const ll N=32768;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int a[maxn];

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		int i;
		m--;
		for(i=2;i<=n;i++)
		{
			if(m<0) break;
			m-=a[i];
			m--;
		//	cout<<m<<" ";
		}
		//cout<<i<<endl;
		if(m>=a[n]&&i==n+1) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	} 
	return 0;
}

C. Make it Increasing

题目

分析

对数组b可以进行b[i]=\pm a[i]的操作,最后使数组b严格递增,求最小操作次数

因为数据非常小,而且时间给出2s,所以我们采用暴力枚举b数组中每个0的位置,看哪个位置为0这样下来的操作数最小。

注意:数很大,该开long long的要开!!!明明思路正确因为一个long long卡真的很亏555

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=5e3+10;
const ll mod=32768;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
ll a[maxn],b[maxn];

int main()
{
	int n;
	cin>>n;
	ll ans=5e18;
	ll tmp=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		if(i==1||i==n) tmp=1;
		else tmp=2;
		b[i]=0;
		b[i-1]=a[i-1];
		b[i+1]=a[i+1];
		for(int j=i-1;j>1;j--)
		{
			ll tt=(b[j]+1+a[j-1]-1)/a[j-1];
			b[j-1]=a[j-1]*tt;
			tmp+=tt;
		}
		for(int j=i+1;j<n;j++)
		{
			ll tt=(b[j]+1+a[j+1]-1)/a[j+1];
			b[j+1]=a[j+1]*tt;
			tmp+=tt;
		}
		ans=min(ans,tmp);
	/*	cout<<i<<" "<<tmp<<endl;
		for(int i=1;i<=n;i++)
		{
			cout<<b[i]<<" ";
		}
		cout<<endl;*/
	}
	cout<<ans<<endl; 
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值