F-Finding the Order


题意
大水题,A和B在一条线上,C和D在一条线上,给定AC,AD,BC,BD的距离,判断是AB||CD还是AB||DC(C和D的位置不同,“CD"和“DC”不一样)
思路
根据三角形两边之和大于第三边,中间交叉两边之和必定大于两边的两条线之和,判断AC+BD和AD+BC的大小即可
代码
#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;
if(a+d>b+c)puts("AB//CD");
else puts("AB//DC");
}
return 0;
}
B-Basic Gcd Problem


题意
给你一个n和c,计算
思路
我们发现每一次递归都会乘一次c,而每一次递归的条件便是x是否为质数,所以可以得出最后的答案为cn的质因子个数
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+5;
const int mod = 1e9 + 7;
ll qmi(int a,int b){ll res=1%mod;while(b){if(b&1)res=res*a%mod;b>>=1;a=(ll)a*a%mod;}return res;}
int ans[N];
void op(int x){
if(ans[x])return;
for(int i = 2;i <= x / i; i ++){
if(x % i == 0){
op(x / i);
ans[x] = ans[x / i] + 1;
return ;
}
}
ans[x] = 1;
return ;
}
void init(){
ans[0] = 1;
for(int i = 2;i < N;i ++)op(i);
}
int main(){
init();
int _;
scanf("%d",&_);
while(_--){
int n,c;
scanf("%d%d",&n,&c);
printf("%lld\n",qmi(c,ans[n]));
}
return 0;
}
H-Harder Gcd Problem


题意
1-n的数,从中选出m对数,使gcd(a1,bi)>1,让m尽可能大,并输出这m对对应的数字
思路(参考牛客题解第二篇)
m肯定是固定的,可以确定m是(n-1-大于n/2的质数个数)/2,因为1和大于n/2的质数肯定不能匹配。接下来对于质数及其倍数构成的集合,如果当前集合是偶数个,那随意匹配,如果是奇数个,保留当前质数*2(使留下的数的个数最多),剩下的数偶数个随意匹配。
代码
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int N = 2e5+5;
bool st[N],vis[N];
int p[N],idx,sum[N];
int ans1[N],ans2[N];
void init(){
st[1] = 1;
for(int i = 2; i <=100000; i ++){
if(!st[i])p[++idx] = i;
for(int j = 1;j <= idx && p[j] * i <= 100000;j ++){
st[p[j] * i] = 1;
if(i % p[j] == 0)break;
}
}
}
void solve(){
int n,cnt = 0;
cin >> n;
for(int i = 1; i <= n; i ++)vis[i] = 0;
int k = n / 2;
int pos = upper_bound(p + 1,p + 1 + min(idx,k),k) - p -1;
for(int i = pos;i >= 1;i --){
int now = 0;
sum[++now] = p[i];
for(int j = 2;p[i] * j <= n; j ++){
int mul = p[i] * j;
if(!vis[mul])sum[++now] = mul;
}
if(now & 1){
ans1[++cnt] = sum[1];
ans2[cnt] = sum[3];
vis[sum[1]] = 1;
vis[sum[3]] = 1;
for(int i = 4;i <= now ;i+=2)
ans1[++cnt] = sum[i],
ans2[cnt] = sum[i+1],
vis[sum[i]] = 1,
vis[sum[i+1]] = 1;
}
else {
for(int i = 1; i <= now; i += 2)
ans1[++cnt] = sum[i],ans2[cnt] = sum[i + 1],
vis[sum[i]] = 1,vis[sum[i + 1]] = 1;
}
}
printf("%d\n",cnt);
for(int i = 1;i <= cnt;i ++)
printf("%d %d\n",ans1[i],ans2[i]);
}
int main(){
init();
int _;cin>>_;while(_--)solve();
return 0;
}
这篇博客介绍了三道数学竞赛题目,包括线性关系的判断和基本与更复杂的最大公约数问题。对于F题,通过三角形性质判断线段是否平行;B题求解涉及质因数的递归问题;H题则探讨在限制条件下如何最大化选择数对使得它们的最大公约数大于1。

4535

被折叠的 条评论
为什么被折叠?



