2020牛客暑期多校训练营(第四场)FBH题解

发布于 2020-07-20  0 次阅读


F.Finding the Order

思路:

签到题,判断ACD是否等腰,等腰就判断c,d中谁更长,不等腰就直接判断a,b谁更长

AC Code:

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const double pi = acos(-1.0);
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
int t, a ,b, c, d;
void solve(){
    cin>>a>>b>>c>>d;
    if(a==b){
        if(c>d) cout<<"AB//CD"<<endl;
        else    cout<<"AB//DC"<<endl;
    }
    else if(a>b)    cout<<"AB//DC"<<endl;
    else    cout<<"AB//CD"<<endl;
    return ;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    cin>>t;
    while(t--)  solve();
    return 0;
}

B.Basic Gcd Problem

思路:

很明显答案肯定为c的次方,对于每个数应该尽可能的让次方大,也就是多进行相乘转换,所以对每个数应该取最大的因子。可以提前打表计算每个数的最大因子求次方数,然后快速幂求答案

AC Code:

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int M=1e9 + 7;
const int N=1e6 + 5;
typedef long long ll;
// #define TDS_ACM_LOCAL
int t;
ll n, c, cnt;
bool vis[N];
int prime[N], p[N], x;
void oulasai()
{
    vis[1]=true;
    int n=1e6;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]) prime[x++]=i, p[i]=i;
        for(int j=0;j<x;j++)
        {
            if(i*prime[j]>n) break;
            vis[i*prime[j]]=true;
            p[i*prime[j]]=prime[j];
            if(i%prime[j]==0) break;
        }
    }
}

ll quick_pow(ll a, ll b)
{ 
	ll res = 1;
	while (b)
	{
		if (b & 1)  res = res * a % M;
		a = a * a % M;
		b >>= 1;
	}
	return res;
}

void solve(){
    scanf("%lld %lld", &n, &c);
    if(!vis[n]) printf("%lld\n", c%M);
    else{
        cnt=0;
        while(n!=1){
            n/=p[n];
            cnt++;
        }
        printf("%lld\n", quick_pow(c, cnt));
    }   
    return ;
}

int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    oulasai();
    scanf("%d", &t);
    while(t--)  solve();
    return 0;
}

H.Harder Gcd Problem

思路:

对2~n的数按照最大质因数进行分类后从大到小匹配,很明显大于n/2的质数是没法匹配到的,所以从n/2往下就行匹配,将质因数的偶数倍的数字全部提出到后面的2为质因数时进行处理,其他的数字两个一组存入,如果只有一个数,则将其和2倍存下,最后对2为质因数的时候匹配,可能会剩下一个值(总数为奇数)

AC Code:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
typedef long long ll;
const int N=2e5 + 10;
int t, n, idx, k, i, j;
int prime[N], vis[N], temp[N];
vector<pair<int,int>>ans;
void init(){
    for(int i=2; i<N; i++){
        if(!prime[i]){
            for(int j=2*i; j<N; j+=i)
                prime[j]=1;
        }
    }
}

void solve(){
    cin>>n;
    memset(vis, 0, sizeof vis);
    ans.clear();
    for(i=n/2; i>2; i--){
        if(!prime[i]){
            idx=0;
            for(j=i; j<=n; j+=i*2){
                if(!vis[j])
                    temp[++idx]=j;
            }
            for(k=idx; k>1; k-=2){
                ans.push_back({temp[k], temp[k-1]});
                vis[temp[k]]=vis[temp[k-1]]=1;
            }  
            if(k==1){
                ans.push_back({temp[k]*2, temp[k]});
                vis[temp[k]*2]=vis[temp[k]]=1;
            }
        }
    }
    idx=0;
    for(i=2; i<=n; i+=2){
        if(!vis[i])
            temp[++idx]=i;
    }
    for(i=idx; i>1; i-=2)
        ans.push_back({temp[i], temp[i-1]});
    cout<<ans.size()<<endl;
    for(auto u: ans)
        cout<<u.first<<" "<<u.second<<endl;
    return ;
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    init();
    cin>>t;
    while(t--)  solve();
    return 0;
}


平平无奇的大学在读本科生