A题:https://codeforces.com/contest/1285/problem/A
题意:机器人初始位置为0,给了一串指令告诉机器人是往左走一格还是右走一格,部分指令可能不会实行,问机器人最终可能的位置的情况数。
思路:这道题的话,L,R的个数加一即为答案。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
int n;
string s;
cin>>n>>s;
int ans1=0,ans2=0;
for(int i=1; i<=s.size(); i++)
{
if(s[i]=='L')
ans1++;
else
ans2++;
}
cout<<ans1+ans2+1<<endl;
return 0;
}
B题:https://codeforces.com/contest/1285/problem/B
题意:给你一个长度为n的序列,这个序列的总和记为sum,问你任意的一个子序列的总和是不是都严格小于sum( 不包括[1,n] ),如果是输出YES,否则输出NO。
思路:这道题的话,我们发现只有3种情况,左边,中间,右边。
我们记序列的总和为sum
如果不满足条件的在左边,说明左边一定>=sum,那我们换位考虑一下右边,是不是右边一定<=0。
如果不满足条件的在右边,说明右边一定>=sum,那我们换位考虑一下左边,是不是左边一定<=0。
如果不满足条件的在中间,说明中间一定>=sum,那么左右两边至少有一个区域总和一定是<=0的。
综上:从头和从尾遍历序列,如果累加的和<=0,直接输出NO,否则输出YES。
我们从1开始向后累加序列的值,如果累加的值小于等于0,则输出NO;
从n开始向前累加序列的值,如果累加的值小于等于0,则输出NO;
否则输出YES。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
ll a[maxx];
int n;
ll solve()
{
ll sum=0;
for(int i=1; i<=n; i++)
{
sum+=a[i];
if(sum<=0)
return 0;
}
sum=0;
for(int i=n; i>=0; i--)
{
sum+=a[i];
if(sum<=0)
return 0;
}
return 1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];
if(solve())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
C题:https://codeforces.com/contest/1285/problem/C
题意:给定一个数字x≤10^12,求两个数字a,b使得max(a,b)尽可能的小且lcm(a,b)=x。
思路:这道题的话,首先,两个数字要互质;第二:两个数字尽可能的接近。为了让两个数字尽量接近,那么就可以直接开个根号,然后往前枚举,开根号后数据是10^6,gcd的复杂度在log,可以通过。
AC代码:
#include<bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
ll gcd(ll a, ll b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
ll x;
cin>>x;
if(x==1)
{
cout<<"1 1"<<endl;
return 0;
}
ll a=sqrt(x);
while(1)
{
ll b=x/a;
if(a*b==x && gcd(a,b)==1)
{
cout<<a<<" "<<b<<endl;
return 0;
}
a--;
}
return 0;
}
D题:https://codeforces.com/contest/1285/problem/D
题意:给定一个序列ai,找一个数字使得max1≤i≤nai∧X最小,求出这个最小值。
思路:这道题的话,是贪心+分治。从最高位开始贪心,如果此时数组元素的这一位全为0或者全为1,那么可以把它们全部贪掉。如果有的是1,有的是0,那说明这一位是躲不掉的,这一位肯定为1,所以在返回的时候加上一个1<<i。而对于后面的数字分治取最小值即可。
AC代码:
#include<bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
vector<int>a;
int n;
int solve(vector<int>v, int bit)
{
if(bit<0 || v.size()==0)
return 0;
vector<int>z,o;
for(int i=0; i<v.size(); i++)
{
if((v[i]>>bit)&1)
z.push_back(v[i]);
else
o.push_back(v[i]);
}
if(o.size()==0)
return solve(z,bit-1);
if(z.size()==0)
return solve(o,bit-1);
return (min(solve(o,bit-1),solve(z, bit-1))|1<<bit);
}
int main()
{
cin>>n;
for(int i=1,x; i++<=n;)
{
cin>>x;
a.push_back(x);
}
cout<<solve(a,30)<<endl;
return 0;
}