题解链接:http://icebound.cc/2019/05/25/hbcpc2019.html

文章目录

  • 热身赛 511
  • 2164 B.Icebound and Sequence
  • 2165 C.分治
  • 2166 D.榜单
  • 2168 F.Takes Apples
  • 2169 G.点我
  • 2170 H.天神的密码
  • 2172 J.舔狗
  • 2173 K.河北美食
  • 2174 L. Smart Robot

热身赛 511

Description
给定n,m,请你计算[1,n!]范围内有多少数字能被m整除。由于答案很大,请输出答案对10e9+7取模的结果。

Input
第一行一个整数T,代表接下来有T组数据
接下来每组数据,有两个数字n,m
1<n,m<=1e6

Output
输出答案对10e9+7取模的结果。

Sample input
2
9 3
10 9

Sample output
120960
403200

题意为求 ( n ! / m ) m o d M (n!/ m)~mod~M (n!/m) mod M,可以利用费马小定理将原式化为:
( n ! ∗ m M − 2 ) m o d M (n!*m^{M-2})~mod~M (n!∗mM−2) mod M

再根据乘法的取模公式,进一步将式子化为:
( n ! m o d M ∗ m M − 2 m o d M ) m o d M (n!~mod~M*m^{M-2}~mod~M)~mod~M (n! mod M∗mM−2 mod M) mod M

左边的 n ! m o d M n!~mod~M n! mod M 可以进一步拆分为
[ n m o d M ∗ ( n − 1 ) m o d M ∗ . . . . . . ∗ 1 m o d M ] m o d M [n~mod~M*(n-1)~mod~M*......*1~mod~M]~mod~M [n mod M∗(n−1) mod M∗......∗1 mod M] mod M

右边的 m M − 2 m o d M m^{M-2}~mod~M mM−2 mod M则可以利用快速幂解出

#include <iostream>
#include <algorithm>
using namespace std;
const int M = 1e9 + 7;
const int N = 1e6 + 5;
typedef long long ll;ll res[N];ll mod_pow(ll x, ll n, ll mod)
{ll res = 1; while (n > 0) {if (n & 1) res = res * x % mod;x = x * x % mod;n >>= 1;}return res % mod;
}int main(void)
{res[1] = 1;for (int i = 2; i <= N - 5; i++) {res[i] = (res[i - 1] * i) % M;}int t;ll n, m, ans;cin >> t;while (t--) {cin >> n >> m;ans = res[n] * mod_pow(m, M - 2, M) % M;cout << ans << endl;}return 0;
}

2164 B.Icebound and Sequence


一开始想的是先用等比数列求和公式,再用费马小定理求逆元,结果发现 p 不是质数,不能用费马小定理。

最简单的解法可以使用矩阵快速幂,先推出相应的矩阵,再套板子求答案就可以了。

注意数据的范围,q 的最大是1e9,需要开成long long。

#include <bits/stdc++.h>
using namespace std;typedef vector<int> vec;
typedef vector<vec> mat;
typedef long long ll;ll M;mat mul(mat &A, mat &B)
{mat C(A.size(), vec(B[0].size()));for (int i = 0; i < A.size(); i++) {for (int k = 0; k < B.size(); k++) {for (int j = 0; j < B[0].size(); j++) {C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M;}}}return C;
}mat pow(mat A, ll n)
{mat B(A.size(), vec(A.size()));for (int i = 0; i < A.size(); i++) {B[i][i] = 1;}while (n > 0) {if (n & 1)B = mul(B, A);A = mul(A, A);n >>= 1;}return B;
}ll n;int main(void)
{int t;ll q, n, p;cin >> t;while (t--) {cin >> q >> n >> p;M = p;mat A(2, vec(2));A[0][0] = 1; A[0][1] = 1;A[1][0] = 0; A[1][1] = q;A = pow(A, n);ll res = A[0][1] * q % M;cout << res << endl;}return 0;
}

2165 C.分治


Sample input
2
1
1
3
1 1 2

Sample output
0
2

区间dp

用dp[i][j]表示攻打完第i个国家到第j个国家,共(j-i+1)个国家需要的最小花费。第一层循环枚举区间长度,第二层循环枚举区间左端点,第三层循环枚举最先攻打区间[i,j]内的城市k。

状态转移方程为dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+(j-i)*cost[k])。

复杂度为O( n 3 n^3 n3)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;int t,n;
int cost[105];
long long dp[105][105];int main(void)
{scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&cost[i]);memset(dp,0,sizeof dp);int len,i,j,k;//区间长度,区间左端点,右端点,攻打的国家for(len=2;len<=n;len++)//区间长度for(i=1;i<=n-len+1;i++)//左端点{j=i+len-1;//右端点dp[i][j]=INF;//先初始化为无穷大for(k=i+1;k<j;k++)//攻打的国家dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+(j-i)*cost[k]);dp[i][j]=min(dp[i][j],dp[i+1][j]+(j-i)*cost[i]);//边界情况dp[i][j]=min(dp[i][j],dp[i][j-1]+(j-i)*cost[j]);}printf("%lld\n",dp[1][n]);}return 0;
}

2166 D.榜单

一道大模拟

题解链接:https://blog.csdn.net/weixin_43772166/article/details/91881351

2168 F.Takes Apples

孟大佬的代码 Orz

#include <bits/stdc++.h>
using namespace std;int main()
{int m, n, s;while (cin >> m >> n >> s) {if(n <= s && m % (s + 1) == 0)puts("Bob");elseputs("Alice");}return 0;
}

2169 G.点我


签到题

忘了考虑n等于0时的情况,WA了一发,难受

#include <iostream>
using namespace std; int main(void)
{int n;cin >> n;if (n == 0 || n % 2 == 1)cout << "qiandaoshibai" << endl;elsecout << "qiandaochenggong" << endl;return 0;
}

2170 H.天神的密码


Sample input
2
11 2
100 1

Sample output
4
1

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
typedef long long ll;char s[20];int main(void)
{int t;ll n, k, x, y;cin >> t;while (t--) {cin >> n >> k;x = 1;for (int i = 0; i < k; i++)x *= n;while (x < 1 || x > 9) {y = 0;while (x != 0) {y += x % 10;x /= 10;}x = y;}cout << x << endl;}return 0;
}

2172 J.舔狗

学姐的代码 Orz

#include <bits/stdc++.h>
using namespace std;const int N = 1e6 + 5;
int to[N], deg[N], ans;bool vis[N];
struct node
{int id, d;node() {}node(int a, int b) : id(a), d(b) {}const bool operator<(const node &x) const { return d >= x.d; }
};
priority_queue<node> q;void toposort() {while (q.size()) {node now = q.top(); q.pop();int u = now.id;int v = to[u];if (vis[u] || vis[v]) continue;ans -= 2;vis[u] = vis[v] = 1;deg[to[v]]--;q.push({to[v], deg[to[v]]});}
}int main()
{int n;cin >> n;for (int i = 1; i <= n; ++i) {cin >> to[i];++deg[to[i]];}for (int i = 1; i <= n; ++i) {if (i != to[i]) {q.push({i, deg[i]});}}ans = n;toposort();cout << ans << endl;return 0;
}

2173 K.河北美食



Sample input
5 3
water 100
flour 20
cabbage 71
pork 12
bean 5
2 water 20 flour 5
3 water 70 cabbage 54 pork 10
5 water 1 flour 1 cabbage 1 pork 2 bean 1

Sample output
YES
water 9
flour 14
cabbage 16
bean 4

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;string arr[N];
map<string, int> mp;int main(void)
{int n, m, a;string s;cin >> n >> m;for (int i = 0; i < n; i++) {cin >> s >> a;mp[s] = a;arr[i] = s;}bool flag = 1;int k, t;while (m--) {cin >> k;while (k--) {cin >> s >> t;mp[s] -= t;if (mp[s] < 0) {flag = 0;}}}if (flag == 0) {cout << "NO" << endl;} else {cout << "YES" << endl;for (int i = 0; i < n; i++) {if (mp[arr[i]] != 0) {cout << arr[i] << " " << mp[arr[i]] << endl;}}}return 0;
}

2174 L. Smart Robot

因为需要记录走过的数字,可以判断出数组不会很大,在1e7左右,进而推断出机器人最多走7步。

需要用一个变量来记录步数,大于等于7就返回

#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 5;int n;
int ma[55][55];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
bool vis[N];void dfs(int x, int y, int state, int cnt)
{if (cnt >= 7) {return;}vis[state] = 1;for (int i = 0; i < 4; i++) {int nx = x + dx[i], ny = y + dy[i];if (nx >= 0 && nx < n && ny >= 0 && ny < n) {dfs(nx, ny, 10 * state + ma[nx][ny], cnt + 1);}}
}int main(void)
{cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {cin >> ma[i][j];}}for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {dfs(i, j, ma[i][j], 0);}}for (int i = 0; i <= N - 5; i++) {if (vis[i] == 0) {cout << i << endl;break;}}return 0;
}

2019hbcpc(第三届河北省大学生程序设计竞赛)相关推荐

  1. 秦皇岛计算机编程大赛,关于举办第三届河北省大学生程序设计竞赛燕山大学选拔赛的通知...

    为提高我校本科生程序设计能力.选拔优秀学生组队参加"第三届河北省大学生程序设计竞赛(HCPC2019)",学校决定组织"第三届河北省大学生程序设计竞赛选拔赛", ...

  2. 2019河北省大学生程序设计竞赛(部分题解)

    2019河北省大学生程序设计竞赛 B.Icebound and Sequence B题题解 G.点我 签到题 H.天神的密码 签到题 #include <iostream> #includ ...

  3. 2019河北省大学生程序设计竞赛题解(一)

    2019河北省大学生程序设计竞赛题解(一) B Icebound and Sequence G 点我 H 天神的密码 K 河北美食 L smart robot 下面是一些这次比赛的较简单题目的题解 题 ...

  4. 2019河北省大学生程序设计竞赛部分题题解

    2019河北省大学生程序设计竞赛 文章目录 A. Battle of Balls B. Icebound and Sequence C. 分治 E. Paper Plane Fly Away F. T ...

  5. 2019河北省大学生程序设计竞赛(重现赛)

    B: 链接:https://ac.nowcoder.com/acm/contest/903/B 来源:牛客网 题目描述 Icebound hates math. But Imp loves math. ...

  6. 2019河北省大学生程序设计竞赛(重现赛)B 题 -Icebound and Sequence ( 等比数列求和的快速幂取模)...

    题目链接:https://ac.nowcoder.com/acm/contest/903/B 题意: 给你 q,n,p,求 q1+q2+...+qn 的和 模 p. 思路:一开始不会做,后面查了下发现 ...

  7. 2018第二届河北省大学生程序设计竞赛题解

    icebound的账单 题目描述 icebound从小就有记账的习惯.又到了月末icebound统计资金状况的时候.icebound每个月除了不停的挥霍以外,有时他会良心发现,勤工俭学,因此会有一些微 ...

  8. 2017第一届河北省大学生程序设计竞赛题解

    超级密码 小明今年9岁了,最近迷上了设计密码!今天,他又设计了一套他认为很复杂的密码,并且称之为"超级密码". 说实话,这套所谓的"超级密码"其实并不难:对于一 ...

  9. 舔狗【2019河北省大学生程序设计竞赛 J题】

    题目描述 > "舔狗舔狗, > 舔到最后, > 一无所有." 有 n 只舔狗,每只舔狗的心中都有自己朝思暮想的一位. 每个人虽然受到了一万次拒绝,还毅然第一万零一 ...

最新文章

  1. C++ 多线程:互斥对象 lock_gurad
  2. 10个工程师,9个不合格!
  3. mysql的存储过程基本使用
  4. Navicat连接SQL Server报错未发现数据源名称并且未指定默认驱动程序
  5. Delphi Qjson
  6. 破烂微软的.NET IDE环境
  7. solaris11-text-安装GUI(gnome)
  8. android gradle错误,Android studio gradle错误与顶级异常
  9. 【数据结构】平衡二叉树
  10. 【Express】—get根据不同的参数返回不同的数据
  11. 日期时间格式与时间戳互转
  12. ExtJs6学习(五)【Extjs MVC开发模式详解】
  13. 基于Spring Boot的人力资源管理系统
  14. 阿贝尔分部求和法的应用(二)
  15. oracle里xdb用户,修改Oracle XDB默认监听端口
  16. 浅谈 NCSI 及其在 Linux 上的实现
  17. Bugku 分析 特殊后门(wireshark流量包分析)
  18. 密码库LibTomCrypt学习记录——(2.3)分组密码算法的工作模式——ECB代码示例
  19. 【历史上的今天】7 月 8 日:PostgreSQL 发布;SUSE 收购 K8s 最大服务商;动视暴雪合并
  20. C语言中指针*p、p以及p之间的区别以及*p和**p的区别

热门文章

  1. win10添加右键菜单打开VSCode
  2. 改写《魔塔》后篇01:在地图上绘制怪物
  3. javascript异步加载
  4. 框架Dubbo原理 机制
  5. mysql、oracle、sqlserver的默认端口号
  6. unity3D4.0菜单翻译
  7. iOS. iphone/iPad中的尺寸、安全区,导航高度、机型判断
  8. 词嵌入之 Word2Vec
  9. 计算机办公软件四级全部试题,计算机等级考试题库,一级MS Office试题【汇总】...
  10. percona mysql 5.5_Percona-mysql server 5.5升级5.6