7.20 18级牛客多校第四场

比赛过程

  吃罚时吃到死的一场,三题垫底水平。

题解

A

题意
解法
代码

B

题意


  然后给你一堆 n , c n,c n,c,让你求 f c ( n ) f_c(n) fc(n) 的最大值。

解法

  其实就是分解n,最好的情况是每次消掉n的一个质因子,所以答案应该是 C n 的 质 因 子 个 数 C^{n的质因子个数} Cn

代码

这题其实有很多写法,下面这个是个递推的写法。

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
#define FOR(a,b,c) for(int a=b;a<=c;a++)
using namespace std;
const ll mod = 1e9+7;
ll powmod(ll a,ll b){ll ans = 1;a %= mod;while(b){if(b & 1){ans = ans * a % mod;b--;}b >>= 1;a = a * a % mod;}return ans;}
const int maxn = 1e6 + 5;
long long PRIMES[223] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409};
ll cnt[maxn] = {0};
int main() {
    IO;
    FOR(i,1,1000000){
        FOR(j,0,168){
            if(i%PRIMES[j]==0){
                cnt[i] = cnt[i / PRIMES[j]] + 1;
                break;
            }
        }
        if(cnt[i]==0&&i!=1) cnt[i]++;
    }
    int t;
    cin >> t;
    while(t--){
        ll n, c;
        cin >> n >> c;
        cout << powmod(c, cnt[n]) << endl;
    }
    return 0;
}

C

题意
解法
代码

D

题意
解法
代码

F

题意

  有四个点 A , B , C , D A,B,C,D A,B,C,D,分别在两条平行线上( A B 一 条 , C D 一 条 AB一条,CD一条 ABCD),给出 A C , A D , B C , B D AC, AD, BC, BD AC,AD,BC,BD 四个距离,问是 A B / / C D AB//CD AB//CD 还是 A B / / D C AB//DC AB//DC

解法

  很遗憾的一道题,如果看的早的话我感觉甚至可以拼一血,很容易就能想到求从 C C C A , B A,B A,B 两点的距离差以及从 D D D A , B A,B A,B 两点的距离差,比较即可。

代码
#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;
        a -= c;
        b -= d;
        if(a<b)
            cout << "AB//CD" << endl;
        else
            cout << "AB//DC" << endl;
    }
    return 0; 
}  

H

题意

  把 1 − n 1-n 1n 中的数两两组合,使得每一组的 G C D GCD GCD 大于1,问最多有多少组。

解法

   先预处理出所有的质数,从大到小遍历质数,假如遇到某个质数 a a a,假设 a , 2 a , 3 a , 4 a , 5 a , 6 a a,2a,3a,4a,5a,6a a,2a,3a,4a,5a,6a 都小于n,则就让 a a a 6 a 6a 6a 4 a 4a 4a 5 a 5a 5a 2 a 2a 2a 3 a 3a 3a 配对即可,如果倍数个数是奇数,就把 2 a 2a 2a 留出来。

代码
#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
#define FOR(a,b,c) for(int a=b;a<=c;a++)
#define RFOR(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
typedef pair<int,int> P;
const ll mod = 1e9+7;
const int maxn = 2e5 + 5;
ll v[maxn] = {0}, prime[maxn], Cnt = 0;//v为最小质因子
int vis[maxn];
vector<P> ans;
void getpri(ll n) {for (ll i = 2; i <= n; ++i) {if (!v[i]) { v[i] = i; prime[++Cnt] = i;}for (ll j = 1; j <= Cnt; ++j) {if (prime[j] > v[i] || prime[j] * i > n) break; v[i * prime[j]] = prime[j];}}}
int main(){
    IO;
    getpri(maxn - 1);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        FOR(i, 1, n) vis[i] = 0;
        vis[1] = 1;
        ans.clear();
        int cnt = 0;
        RFOR(i,n,2){
            if(v[i]==i){
                int x = i;
                for (int j=n/i*i;j>i;j-=i){
                    if(vis[j]) continue;
                    if(!x) x=j;
                    else
                        cnt++, ans.push_back(P(x,j)), vis[x] = 1, vis[j] = 1, x = 0;
                }
            }
        }
        cout << cnt << endl;
        for(auto i:ans){
            cout << i.first << " " << i.second << endl;
        }
    }
    return 0;
}

I

题意
解法
代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值