链接:牛客小白月赛71_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ
A:猫猫与广告
观察题目,让我们找到一个牌子去遮挡一下另一块牌子,考虑到边对齐,直接进行判断即可,判断的时候记得考虑短边对短边,长边对长边就行;
代码:
#include <iostream>
using namespace std;
int main()
{
int a,b,c,d;
cin >> a >> b >> c >> d;
if(a > b)swap(a,b);
if(c > d)swap(c,d);
if(c >= a && d >= b)cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}
B:猫猫与密信
这里问我们能不能找到love或者任意删除一个字母后字符串,可以直接暴力判断,这里我使用find函数进行查找,这里查找love可以不写,因为查找ove的时候也可以查找到love;
代码:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string s;
cin >> s;
int flag = 0;
if(s.find("ove") != -1 || s.find("lve") != -1 || s.find("loe") != -1 || s.find("lov") != -1)flag = 1;
if(flag)cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}
C:猫猫与数列
我们看一下,会发现就算是最小的情况两个数字都为一,答案也就是5,也就是最多不乘超过五次,那么我们这时候就可以直接暴力。
考虑的每次都是倍数增加就算是最小的2,乘64次之后也会超过LL,所以我们直接进行进行for循环,这样有效避免哦我们的溢出问题,只要发现溢出直接退出即可;
代码:
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
int main()
{
ll p,q;
cin >> p >> q;
ll t = 1;
ll idx = 0;
for(int i = 3;;i ++ )
{
int flag = 1;
t = 1;
for(int j = 1;j <= q;j ++ )
{
t *= p;
if(t > 1e18)
{
flag = 0;
idx = i - 1;
break;
}
}
swap(p,q);
q = t;
if(!flag)break;
}
cout << idx << endl;
return 0;
}
D:猫猫与主人
首先我们观察这个序列,我们发现对于每一个猫猫,只要某个主人的期望友善值在这只猫猫的友善值以下,我们就可以找到一个最大的友善值的主人分给这只猫猫,因为同一个主人可以多次分配,所以不用考虑这个问题。
接着我们发现应该先把主人按期望友善值排序,之后把友善值进行前缀和,求出每个主人及其比他的期望值小的主人他们最大友善值。因为当期望值为9的主人能领养某只猫猫,那么期望值在9一下的主人肯定也能领养这只猫猫,只是友善值不同;
接着对于每一只猫猫,找到对应他的友善值的最大期望值,取出最大友善值,与猫猫的友善值判断,如果还达不到猫猫的期望友善值,说明没有答案,否则就把这个最大友善值分配给这只猫猫。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 2e5 + 10;
PII cat[N], per[N];
int ans[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>cat[i].x;
for(int i=1;i<=n;i++) cin>>cat[i].y;
for(int i=1;i<=m;i++) cin>>per[i].y;
for(int i=1;i<=m;i++) cin>>per[i].x;
sort(per+1,per+1+m);
for(int i=1;i<=m;i++)
{
ans[i]=max(ans[i-1],per[i].y);
}
for(int i=1;i<=n;i++)
{
int l=1,r=m;
while(l<r)
{
int mid=(l+r+1)/2;
if(per[mid].x>cat[i].x) r=mid-1;
else l=mid;
}
if(cat[i].y<=ans[l]) cout<<ans[l]<<' ';
else cout<<-1<<' ';
}
}
E:猫猫与数学
首先我们需要直到有这样一个公式:gcd(a,b)=gcd(a,b-a)。
所以对于这个题目,gcd(a+c,b+c)=gcd(a+c,b-a);
那么对于b-a的所有质因子,我们只需要找到a+c使其能够整除即可。那么基于此我们对b-a进行质因数分解,我们规定b=b-a,只要b%i==0,那么此时我们需要a+c|i,c=i-a%i,对答案进行更新即可,记得把b的这个公因子给除尽。
如果最后发现b仍然大于0,说明需要再更新一次答案。
代码:
#include<iostream>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b)
{
return b?gcd(b,a%b):a;
}
int main()
{
LL n,m;
cin>>n>>m;
if(n>m) swap(n,m);
if(gcd(n,m)>1)
{
cout<<0;
}
else
{
m-=n;
if(m==0)
{
cout<<1;
}
else if(m==1)
{
cout<<-1;
}
else
{
LL ans=1e18;
for(LL i=2;i<=m/i;i++)
{
if(m%i==0)
{
ans=min(ans,i-n%i);
while(m%i==0) m/=i;
}
}
if(m>1) ans=min(ans,m-n%m);
cout<<ans;
}
}
}
/*
2 1000000009
*/