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;
}