Codeforces Round #783 (Div. 2) 题解

A 题目链接:https://codeforces.com/contest/1668/problem/A

input:

6
1 1
2 1
1 3
4 2
4 6
10 5

output:

0
1
-1
6
10
17

题意:

给 n * m 大小的地图 ,从(1,1)出发,终点为(n,m),每次可以选择上下左右其中一个方向移动一格,但不能连续两次向同一个方向走,问最少几步能达到终点,不能到达则输出-1

思路:

首先,对于 n , m较短的那边,我们可以到达而不花费多余代价。此时长的那边剩余的部分,我们需要多花费(abs(n - m)- 1)的代价,对于 abs(n - m) % 2 == 0 的情况,还需要多花费一个代价

如果某一个数等于1,另一个数大于等于3,那么无解,输出-1

代码如下:

#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
 
int t,n,m;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		int ans=2*(min(n,m)-1)+2*(max(n,m)-min(n,m))-1;
		if(min(n,m)==1&&max(n,m)>=3)
		{
			cout<<-1<<endl;
			continue;
		}
		if((n-m)%2==0)
			ans++;
		cout<<ans<<endl;
	}
	return 0;
}

B 题目链接:https://codeforces.com/contest/1668/problem/B

input:

6
3 2
1 1 1
2 4
1 1
2 5
2 1
3 8
1 2 1
4 12
1 2 1 3
4 19
1 2 1 3

output:

NO
YES
NO
YES
NO
YES

题意:

有 n 个人, m 把椅子环形放置,第 i 个人入座的限制是:左右各留出至少 ai 个空位。问 m 把椅子够不够这 n 个人入座

思路:

先 sort ,然后从2开始,对于每个人,处理一下其左边的空位限制。因为是环形,所以第 n 个人处理一下左边的空位限制即可

注意开 long long

代码如下:

#include<bits/stdc++.h>
#define endl "\n"
typedef long long ll;
using namespace std;
const int N=2e5+10;
 
int t,n,m;
int a[N];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		ll cnt=1;
		for(int i=2;i<=n;i++)
		{
			cnt+=a[i];
			cnt++;	
		}
		cnt+=a[n]; 
		if(cnt>m)
		{
			cout<<"NO"<<endl;
		}
		else
		{
			cout<<"YES"<<endl;
		}
	}
	return 0;
}

C 题目链接:https://codeforces.com/contest/1668/problem/C

input1:

5
1 2 3 4 5

output1:

4

input2:

7
1 2 1 2 1 2 1

output2:

10

input3:

8
1 8 2 7 3 6 4 5

output3:

16

题意:

有 n 个数的数组 a 和数组 b ,一开始 b 中所有元素均为0.每次可以对数组 b 任意一个元素做出以下操作:

1. bi = bi + ai

2. bi = bi - ai

问最少操作几次,能使数组 b 为升序

思路:

n <= 5000 直接 O(n ^ 2)贪心 + 暴力

首先,如果使数组 b 形成递增,那么一定有一个数没变, 依然是 0(这样最赚)

这样的话,这个0的左边全为负数,右边全为正数

我们枚举每一个位置是0的情况,将两边每一个元素构造为刚好满足情况的数,这样得到局部最优,再将全部情况取最小即可

代码如下:

#include<bits/stdc++.h>
#define endl"\n"
typedef long long ll;
using namespace std;
const int N=5e3+10; 
 
int t,n,m;
ll a[N];
 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	ll ans=0X3F3F3F3F3F3F3F3F;
	for(int i=1;i<=n;i++)
	{
		ll t=0;
		ll cans=0;
		ll m=0;
		for(int j=i-1;j>=1;j--)
		{
			m=t/a[j]+1;
			t=a[j]*m;
			cans+=m;
		}
		t=0;
		for(int j=i+1;j<=n;j++)
		{
			m=t/a[j]+1;
			t=a[j]*m;
			cans+=m;
		}
		ans=min(ans,cans);
	}
	cout<<ans<<endl;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值