牛客算法入门课练习题单

华华教月月做数学

https://ac.nowcoder.com/acm/problem/23046 https://ac.nowcoder.com/acm/problem/24636

链接:https://ac.nowcoder.com/acm/problem/23046
题目描述
找到了心仪的小姐姐月月后,华华很高兴的和她聊着天。然而月月的作业很多,不能继续陪华华聊天了。华华为了尽快和月月继续聊天,就提出帮她做一部分作业。 月月的其中一项作业是:给定正整数A、B、P,求ABmod  PA^B\mod PABmodP的值。华华觉得这实在是毫无意义,所以决定写一个程序来做。但是华华并不会写程序,所以这个任务就交给你了。 因为月月的作业很多,所以有T组询问。

输入描述:
第一行一个正整数T表示测试数据组数。
接下来T行,每行三个正整数A、B、P,含义如上文。

输出描述:
输出T行,每行一个非负整数表示答案。

示例
输入
2
2 5 10
57284938291657 827493857294857 384729583748273
输出
2
18924650048745

解析:很明显要用矩阵快速幂来求解,但是数据的范围达到了18次方了,只用矩阵快速幂会爆long long,而在做快速幂相乘时可以再对数据进行取模,比如ab可以写成a个b相乘,然后可以时1b

2b + 4b......在这个过程中可以取模免得溢出。

#include 
#include 
#include 
#include 
#include 
#include 
#define mod 1000000007
#define LL long long
using namespace std;
LL p;
LL mpow(LL res,LL ans)
{
LL t = 0;
while(ans){
if(ans & 1){
t = (t + res) % p;
}
res = (res + res) % p;
ans >>= 1;
}
return t;
}
LL mypow(LL A, LL B)
{
LL res = 1, ans = A;
while(B){
if(B & 1)
res = mpow(res,ans);
ans = mpow(ans,ans);
B >>= 1;
}
return res;
}
int main()
{
int T;
cin >> T;
while(T--){
LL A,B;
cin >> A >> B >> p;
LL ans = mypow(A,B);
cout << ans % p << endl;
}
return 0;
}

值周 离散化+差分

https://ac.nowcoder.com/acm/problem/24636

#include <bits/stdc++.h>
#include <iostream>
const int Max = 1e6+5;
#define LL long long
const int inx = INT_MAX; 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//    srand(time(NULL));
//        m = rand() % 1000 + 1;

//交换元素 

typedef struct ss{
    int pos,num;
}ss;

ss s[2 * Max + 5];

bool cmp(ss a,ss b){
    return a.pos < b.pos;
}

int main(){
    int L,M,l,r,i;
    scanf("%d%d",&L,&M);
    for(i = 1; i <= M; i++){
        scanf("%d%d",&l,&r);
        s[2 * i - 1].pos = l;
        s[2 * i - 1].num = 1;
        s[2 * i].pos = r + 1;
        s[2 * i].num = -1;
    }
    sort(s + 1,s + 2*M + 1,cmp); 
    int ans = 0,temp = 0;
    for(i = 1; i <= M * 2; i++){
        temp += s[i].num;
        if(temp == 1 && s[i].num == 1){
            ans += s[i].pos - s[i - 1].pos;
        }
    }
    ans += L - s[2 * M].pos + 1;
    printf("%d",ans);
    return 0;
}

奇妙的拆分

https://ac.nowcoder.com/acm/problem/14709

因为这道题的因子不能够重复,所以选取的因子i*i<n才能够满足,所以可以直接枚举到根号n即可。

#include <bits/stdc++.h>
#include <iostream>
const int Max = 1e6+5;
#define LL long long
const int inx = INT_MAX; 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//    srand(time(NULL));
//        m = rand() % 1000 + 1;

int main()
{
    int T,n,i,ans = 0,temp;
    cin >> T;
    while(T--){
        cin >> n;
        temp = n;
        ans = 0;
        for(i = 1; i <= sqrt(n) + 2; i++){
            if(temp % i == 0 && temp / i > i){
                ans++;
                temp /= i;
            }
            else if(temp / i <= i){
                ans++;
                break;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

切长条:贪心区间选点

https://ac.nowcoder.com/acm/problem/25136


思路:该题相当于问你最少选几个点可以让这些点在区间内能找到,所以先按区间右端点从小到大排序,每次选区间右端点的值去与下一个区间的左端点值比较,这样可以保证这个区间覆盖到下一个区间,如果相同则按左端点从小到大排序。

#include <bits/stdc++.h>
#include <iostream>
const int Max = 1e6+5;
#define LL long long
const int inx = INT_MAX; 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//    srand(time(NULL));
//        m = rand() % 1000 + 1;

//交换元素 

typedef struct ss{
    int x,y;
}ss;

bool cmp(ss a,ss b)
{
    if(a.y != b.y) return a.y < b.y;
    return a.x < b.x;
}

int main()
{
    int N,a,L,i,ans = 0;
    cin >> N;
    ss s[32005];
    for(i = 1; i <= N; i++){
        cin >> s[i].x >> L;
        s[i].y = s[i].x + L;
    }    
    sort(s + 1,s + N + 1,cmp);
    int last = s[0].y;
    for(i = 1; i <= N; i++){
        if(s[i].x >= last){
            ans++;
            last = s[i].y;
        }
    }
    cout << ans;
    return 0;
}

合并果子:堆

https://ac.nowcoder.com/acm/problem/16663


思路:因为要求最少花费的力气,所以每次去合并所有堆中果子数量最少的堆。先把所有的堆合并成一个小根堆,然后每次合并的时候都是去这个小根堆的根,合并后再加入堆中即可得到答案。

#include <bits/stdc++.h>
#include <iostream>
const int Max = 1e6+5;
#define LL long long
const int inx = INT_MAX; 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//    srand(time(NULL));
//        m = rand() % 1000 + 1;

//定义i i(A) i+n i+n(B) i+n+n i+n+n(C) 
int t = 0;
int a[10005];
void Insert(int x)
{
    t++;
    int i,j;
    a[t] = x;
    i = t;
    j = i / 2;
    while(j > 0 && a[i] < a[j]){
        swap(a[i],a[j]);
        i = j;
        j = i / 2;
    }
}

int Pop(){
    int i,j,temp;
    temp = a[1];
    a[1] = a[t];
    t--;
    i = 1;
    j = i * 2;
    if(j + 1 <= t && a[j] > a[j + 1]) j++;
    while(j <= t && a[j] < a[i]){
        swap(a[i],a[j]);
        i = j;
        j = i * 2;
        if(j + 1 <= t && a[j] > a[j + 1]) j++;
    }
    return temp;
}

int main()
{
    int n,i,x,ans = 0;
    cin >> n;
    for(i = 1; i <= n; i++){
        cin >> x;
        Insert(x);
    }
    while(t >= 2){
        int a = Pop();
        int b = Pop();
        ans += a + b;
        Insert(a + b);
    }
    cout << ans;
    return 0;
}
全部评论

相关推荐

把球:这个听过,你加了就会发现是字节的hr
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务