A. Array Rearrangment
将给定的a,b数组从小到大排序,然后a的第i个匹配b的第n-i-1个,若a[i]+b[n-i-1]>x, 则不合法。
#include <bits/stdc++.h>
using namespace std;
int a[100], b[100];
int main()
{
int t;
cin >> t;
while(t--)
{
int n, k;
cin >> n >> k;
for(int i=0; i<n; i++)
{
int temp; cin >> temp;
a[i] = temp;
}
for(int i=0; i<n; i++)
{
int temp; cin >> temp;
b[i] = temp;
}
sort(a,a+n); sort(b,b+n);
int flag = 1;
for(int i=1; i<=n; i++)
if(a[i-1]+b[n-i]>k) flag = 0;
if(flag) cout <<"Yes\n";
else cout <<"No\n";
}
return 0;
}
B. Elimination
输入a,b,c,d, 输出max(a+b, c+d)即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int a,b,c,d;
cin >> a >> b>> c >> d;
cout << max(a+b,c+d) << endl;
}
return 0;
}
C. Division
题目给定两个整数p, q。要求输出一个尽可能大的数x,满足
p
%
x
=
=
0
&
x
%
q
!
=
0
p\%x==0 \& x\%q!=0
p%x==0&x%q!=0。
如果p%q!=0,那么直接输出p。
否则,我们先对q进行质因数分解,并记录相同的质因数出现的个数。
对q出现的所有不相同的质因数,我们可以称之为f, 我们也要找到质因子f在p中所有质因子出现的次数。
此时我们记质因子f在p中出现n次, 在q中出现m次, 那么 p/(f^(n-m+1)) 将是一个满足
p
%
x
=
=
0
&
x
%
q
!
=
0
p\%x==0 \& x\%q!=0
p%x==0&x%q!=0的数字。
遍历所有q的不同质因子,找到最大的该数字即可。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100100;
typedef long long ll;
bool isnp[MAXN];
vector<int> primes; // 质数表
vector<int> f;
struct {
int num, cnt;
} a[100100];
void init(int n) //欧拉筛
{
for (int i = 2; i <= n; i++)
{
if (!isnp[i])
primes.push_back(i);
for (int p : primes)
{
if (p * i > n)
break;
isnp[p * i] = 1;
if (i % p == 0)
break;
}
}
}
void func(ll n) //分解质因数
{
for(auto p:primes)
{
if(n%p==0)
{
f.push_back(p);
n/=p;
}
while(n%p==0)
{
f.push_back(p);
n/=p;
}
}
if(n!=1) f.push_back(n);
int cnt=0;
for(auto p:f)
{
if(p!=a[cnt].num) a[++cnt].num = p, a[cnt].cnt=1, a[0].num++;
else a[cnt].cnt++;
}
}
ll sol(ll p,int i)
{
int rev = 0;
while(p%(ll)a[i].num==0)
{
p/=a[i].num;
rev++;
}
ll ans = 1;
for(int j=1; j<=(rev-a[i].cnt+1); j++)
ans *= a[i].num;
return ans;
}
int main()
{
int t;
cin >> t;
init(100000);
while(t--)
{
{
f.clear();
memset(a, 0, sizeof a);
}
ll p, q;
cin >> p >> q;
int cnt = 0;
if(p%q) cout << p << endl;
else
{
func(q);
ll ans=0x3fffffffffffffff;
for(int i=1; i<=a[0].num; i++)
ans = min(ans, sol(p,i));
cout << p/ans << endl;
}
}
return 0;
}
D Extreme Subtraction
题目大意:
给t组样例。每组样例,包含一个整数n,以及n长度的数组a。
对数组a,是否能通过以下两种操作使得全部元素为0。
操作一,选择数组从开头开始、连续的区间,每个元素减一。
操作二,选择数组从末尾开始、连续的区间,每个元素减一。
解法:
- 对a数组进行差分得到数组b。
- 取出a[0],并将a[0]与b数组中所有的负数相加。
- 判断此时a[0]是否为非负整数,是则可行,输出“Yes",否则不可行,输出”No“。
#include <bits/stdc++.h>
using namespace std;
int a[100100], b[100100];
int main()
{
int t; cin >> t;
while(t--)
{
int n; cin >> n;
for(int i=0; i<n; i++) cin >> a[i];
b[0] = a[0];
for(int i=1; i<n; i++) b[i] = a[i]-a[i-1];
int ans = a[0];
for(int i=1; i<n; i++) if(b[i]<0) ans += b[i];
if(ans>=0) cout << "Yes\n";
else cout << "No\n";
}
return 0;
}