AcWing第127场周赛笔记

热身计算

热身计算

打卡题 直接输出答案即可

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    cout << 2 * a + 3 * b + 5 * c << endl;    
    return 0;
}

牛棚入住

牛棚入住

模拟题  只需要注意判断1头牛入住的未满牛栏个数 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main()
{
    int n, a, b;
    cin >> n >> a >> b;
    
    int res = 0, p = 0;
    while (n -- )
    {
        int k;
        scanf("%d", &k);
        if (k == 1)
        {
            if (a != 0) a --; // 判断1人房入住情况
            else if (b != 0) b --, p ++ ; // 如果1人房用完了 则判断二人房剩余房间数 如果有就让1人入住 并且用变量p记录入住一人的二人房个数
            else if (p != 0) p --; // 如果二人房被用完 判断只有一人入住的二人房是否用完 如果没有就入住 否则就没有房间住
            else res ++;
        } 
        else 
        {
            if (b != 0) b --; // 根据提议 来两人只能入住空的二人房 所以直接判断二人房是否用完 
            else res += k;
        } 
    }
    
    cout << res << endl;

    return 0;
}

构造矩阵

构造矩形

任填前 n−1 行,m−1 列,每个方格有两种选择,共 2^(n-1)(m-1) 种。由于每行每列乘积为 k,下图中区域 A,B的填法固定,进而,右下角 x = k/A = k/B

若 A=B 则有解,否则无解。设前 n−1 行,m−1 列的乘积为 C,则

AC=k^n−1
BC=k^m−1
C≠0,则 A=B 等价于 k^n−1 = k^m−1。当 k=1 时,等式恒成立。当 k=−1 时,仅当 n,m 奇偶性相同时成立。

这题的数据范围n,m给了10^18次方 n*m达到了10^38级别 那么肯定会爆int 我们可以用欧拉函数或者费马小定理来缩小数据范围 用两次快速幂也可以解决

复习下费马小定理:

假如p是 质数,且(a,p)=1,那么 a (p-1)≡1(mod p)。即:假如a是 整数,p是 质数,且a,p 互质(即两者只有一个 公约数1),那么a的(p-1)次方除以p的 余数 恒等于1

附代码

(快速幂做法)

#include <iostream>

using namespace std;
typedef long long LL;

const int MOD = 1e9 + 7;

LL n, m;
int k;

int qmi(int a, LL b) {
  int r = 1 % MOD;
  while (b) {
    if (b & 1) r = (LL)r * a % MOD;
    a = (LL)a * a % MOD;
    b >>= 1;
  }
  return r;
}

int main() {
  cin >> n >> m >> k;

  if (n + m & 1 && k == -1) cout << 0 << endl;
  else cout << qmi(qmi(2, n - 1), m - 1) << endl; // 两次快速幂降复杂度

  return 0;
}

(费马小定理做法)

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
const int p = 1e9 + 7;

LL qmi(LL a, LL b, LL k)
{
    LL res = 1;
    while (b)
    {
        if (b & 1) res = res * a % k;
        a = a * a % k;
        b >>= 1;
    }
    
    return res;
}
int main()
{
    LL n, m, k;
    cin >> n >> m >> k;
    
    if (k == -1 && (n % 2) != (m % 2)) puts("0");
    else
    {
        LL t = ((n - 1) % (p - 1)) * ((m - 1) % (p - 1)) % (p - 1); 
        cout << qmi(2, t, p) << endl;
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值