牛客小白月赛35题解

一边做一边写的题解
把每个题我出现的问题展现出来 防止大家踩坑了

A

这个题真的是一个大水题 谁来都是
但是我竟然wa了一发。。。。

string str;
getline(cin,str);//整行读入string

char str2[1024];
cin.getline(str2,1024);//读入char数组

我第一次交的时候是用的gets()编译错误(所以避坑 pat也是会编译错误

#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

const int N = 1e6 + 10;
string a;

int main()
{
    getline(cin,a);
    for (int i = 0; i < a.size(); i ++)
    {
        if (a[i] == '<') cout << "&lt;";
        else if (a[i] == '>') cout << "&gt;";
        else cout << a[i];
    }
    cout << endl;
    return 0;
}

B

全乘在一起在%2当然不可能 每个数字%2就ok了
记得开long long

#include <algorithm>
#include <iostream>

using namespace std;

const int N = 5e6 + 10;
long long a[N], n, num;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++)
    {
        scanf("%lld",&a[i]);
        while (a[i] != 0 &&a[i] % 2 == 0)
        {
            a[i] /= 2;
            num++;
        }
    }
    cout << num << endl;
}

C

快速幂
第n行第m个数就是C(n - 1, m)我知道这个公式但是不知道怎么用快速幂。。。
看题解说这是道模板题 呃。。
雀食我差的有点多 上模板把
求C(n,m)和A(n,m)

typedef long long ll;
const int inf=0x3f3f3f;
const int maxn=1e9+1;
const int mod=1e9+7;
ll a[];//数组大小注意,也要与下面初始化一致
ll Pow(ll a,ll b){
    a%=mod;
    ll ans = 1;
    while(b)
    {
        if(b&1)
            ans = (ans*a)%mod;
        a = (a*a)%mod;
        b/=2;
    }
    return ans%mod;
}
ll Quk(ll a,ll b){
    a%=mod;
    ll ans = 0;
    while(b)
    {
        if(b&1)
            ans = (ans+a)%mod;
        a = (a+a)%mod;
        b/=2;
    }
    return ans%mod;
}
ll C(ll n,ll m){
    return Quk(Quk(a[n],Pow(a[n-m],mod-2)),Pow(a[m],mod-2))%mod;
}
ll A(ll n,ll m){
    return Quk(a[n],Pow(a[n-m],mod-2))%mod;
}


int main()
{
    a[0]=a[1]=1;
    for(ll i=2;i<=1000000;i++)
        a[i]=Quk(a[i-1],i);
    //C,A使用均为前面数大


    return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
const int mod = 1e9+7;
ll fact[N],infact[N];
ll qmi(ll a, ll k, ll p)
{
    ll res = 1;
    while (k)
    {
        if (k & 1) res = (ll)res * a % p;
        a = (ll)a * a % p;
        k >>= 1;
    }
    return res;
}

void init(int n)
{
    fact[0] = infact[0] = 1;
    for (int i = 1; i <=n; i ++ )
    {
        fact[i] = (ll)fact[i - 1] * i % mod;
        infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
    }
}

ll c(int  a, int b )
{
    return (ll)fact[a] * infact[b] % mod * infact[a - b] % mod;
}
int main()
{
    int n;
    cin>>n;
    --n;
    init(n);
    ll ans=1;
    for(int i=1; i<=n; ++i)
        ans=ans*c(n,i)%mod;
    cout<<ans<<endl;
}

D

找规律?

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;
int a[30];
int main()
{
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); i ++) a[s[i] - 'a'] ++;
    priority_queue<int, vector<int>, greater<int>> q;
    for (int i = 0; i < 26; i ++)
    {
        if (a[i]) q.push(a[i]);
    }
    if (q.size() == 1) cout << q.top() << endl;
    else { 
        int res = 0;
        while (q.size() > 1)
        {
            int i = q.top(); q.pop();
            int j = q.top(); q.pop();
            res += i + j;
            q.push(i + j);
        }
        cout << res << endl;
    }
    return 0;
}

E

四面体体积的公式
1.过一顶点的三向量设为a,b,c,所求四面体的体积就是|(a×b)·c/6
2.直接利用行列式计算
                              | 1    1    1    1  |

          v     =1/6 * det    | x1    x2   x3   x4|

                              | y1   y2   y3   y4 |

                              | z1   z2    z3   z4|
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 10;
double x[N], y[N], z[N];

int main()
{
    for (int i = 1; i <= 4; i ++)
    {
        scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);
    }
    double sum = x[2]*y[3]*z[4]+y[2]*z[3]*x[4]+x[3]*y[4]*z[2]-x[4]*y[3]*z[2]-x[3]*y[2]*z[4]-y[4]*z[3]*x[2];
    sum -=  x[1]*y[3]*z[4]+y[1]*z[3]*x[4]+x[3]*y[4]*z[1]-x[4]*y[3]*z[1]-x[3]*y[1]*z[4]-y[4]*z[3]*x[1];
    sum += x[1]*y[2]*z[4]+y[1]*z[2]*x[4]+x[2]*y[4]*z[1]-x[4]*y[2]*z[1]-x[2]*y[1]*z[4]-y[4]*z[2]*x[1];
    sum -= x[1]*y[2]*z[3]+y[1]*z[2]*x[3]+x[2]*y[3]*z[1]-x[3]*y[2]*z[1]-x[2]*y[1]*z[3]-y[3]*z[2]*x[1];
    if (sum < 0) sum = (-sum) / 6;
    else sum = sum / 6;
    printf("%.12f\n",sum);
    return 0;
}

F

逆序对

#include <algorithm>
#include <iostream>

using namespace std;

const int N = 1e6 + 10;
long long sum,t;
long long a[N], temp[N];
int n;

void merge_sort(int l, int r)//逆序对的模板(也不全是
{
    if (l >= r) return ;
    int mid = l + r >> 1;
    merge_sort(l, mid);
    merge_sort(mid + 1, r);
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
    {
        if (a[i] < a[j]) temp[k ++] = a[i ++];//这里是<不是<=(前面与这个数相同的有算进去)
        else {
            temp[k ++] = a[j ++];
            sum += mid - i + 1;
        }
    }
    while (i <= mid) temp[k ++] = a[i ++];
    while (j <= r) temp[k ++] = a[j ++];
    for (int i = l, j = 0; i <= r; i ++, j ++) a[i] = temp[j];
}

int main()
{
    scanf("%lld",&n);
    for (int i = 1; i <= n; i ++)
    {
        scanf("%lld",&t);
        a[i] = a[i - 1] + t;
        if (a[i] <= 0) sum ++;//负数的自己不能和自己
    }
    merge_sort(1, n);
    printf("%lld", (long long)n * (long long)(n + 1) / 2 - sum);
    return 0;
}

H

我但是看见这道题是不敢下手(不知道怎么处理输入

#include <algorithm>
#include <iostream>

using namespace std;

string a;
string b = "name=\"csrfmiddlewaretoken\"";

int main()
{
    while (cin >> a)
    {
        if (a == b)
        {
            cin >> a;
            for (int i = 7; i < a.size() - 2; i ++) cout <<a[i];
            break;
        }
    }
    return 0;
}

J

背包dp

#include <algorithm>
#include <iostream>

using namespace std;

const int N = 1e4 + 10;
struct jg{
    int a, b, p;
    bool operator<(jg w)
    {
        return p < w.p;//按照用完优惠券之后价格  从小到大排序
    }
};
jg q[N];
int n, k;
int f[N];//[现在的钱数] = 优惠后的钱数

int main()
{
    cin >> n >> k;
    for (int i = 0; i <= k; i ++) f[i] = i;
    for (int i = 1;i <= n; i ++)
    {
        cin >> q[i].a >> q[i].b;
        q[i].p = q[i].a - q[i].b;
    }
    sort(q + 1, q + n + 1);
    for (int i = 1; i <= n; i ++)
    {
        for (int j = k; j >= q[i].a; j --)
            f[j] = min(f[j], f[j - q[i].b]);
    }
    printf("%d",f[k]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值