2021年ACM竞赛班训练(十)

  • A: 是签到题
  • 题目描述
  • 输入
  • 思路
  • B: N!的位数 数论,花犇,CCF三級
  • 题目描述
  • 输入
  • 输出
  • 思路
  • C: The Mountain
  • 题目描述
  • 输入
  • 输出
  • 样例输入
  • 样例输出
  • 思路
  • D: Sudoku
  • 题目描述
  • 输入
  • 输出
  • 样例输入
  • 样例输出
  • 思路
  • E: TYVJ 1042 表达式计算3
  • 题目描述
  • 输入
  • 输出
  • 样例输入
  • 样例输出
  • 思路
  • 代码
  • F: 逆序对
  • 题目描述
  • 输入
  • 输出
  • 样例输入
  • 样例输出
  • 思路
  • 代码

A: 是签到题

题目描述

zzh和女朋友进了一个规模为n*n的迷宫,女朋友被突然出现的传送门传到了迷宫的另一地点,zzh需要先找到女朋友,再一起去迷宫的出口。
请你帮zzh计算能否找到女朋友并离开迷宫,若能,则输出最小移动步数。

输入

第一行给出一个数字t,表示数据组数(t<=100)
每组数据的第一行为n (n<=600)
接下来的n行,每行为有n个字符的字符串,描述迷宫。
迷宫描述中‘#’表示无法通过的墙壁,‘.'表示可以通过,‘Z’表示zzh的初始位置,‘E’表示迷宫出口,‘G’表示zzh女朋友所在位置。
输出
若zzh能找到女朋友并离开迷宫,则输出最小步数,否则输出-1。

思路

对于迷宫问题,可以使用dfs或bfs,但题目要求求出最短路径,而dfs需要找出所有路径再从所有路径中选出最短的,故使用bfs。我们使用一个数组记录迷宫中每一点到起点的距离,并借助标记数组(标记该点已经走到),可以使得记录距离的数组中的值保持最小,因为已经标记过的点不会再访问,初始化距离数组为-1,若最终数组中某一值仍未-1,表示该点不能被访问到。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e6+10,M=610,inf=0x3f3f3f,mod=1e9+7;
int t;int n;
char g[M][M];
int dist1[M][M];
int dist2[M][M];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int ex,ey;
void bfs(int stx,int sty,int dist[][M])
{queue<pair<int,int>>q;q.push({stx,sty});for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)dist[i][j]=-1;}dist[stx][sty]=0;while(q.size()){auto t=q.front();q.pop();for(int i=0;i<4;i++){int x=t.x+dx[i];int y=t.y+dy[i];if(x<=0||x>n||y<=0||y>n) continue;if(dist[x][y]!=-1) continue;if(g[x][y]=='#') continue;dist[x][y]=dist[t.x][t.y]+1;q.push({x,y});}}
}
int main()
{cin>>t;while(t--){int sx,sy,ex1,ey1;cin>>n;for(int i=1;i<=n;i++) cin>>g[i]+1;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(g[i][j]=='Z') sx=i,sy=j;else if(g[i][j]=='G') ex1=i,ey1=j;else if(g[i][j]=='E') ex=i,ey=j;}}bfs(sx,sy,dist1);bfs(ex1,ey1,dist2);if(dist1[ex1][ey1]!=-1&&dist2[ex][ey]!=-1)cout<<dist1[ex1][ey1]+dist2[ex][ey]<<endl;else cout<<-1<<endl;}}

B: N!的位数 数论,花犇,CCF三級

题目描述

夫夫有一天对一个数有多少位数感兴趣,但是他又不想跟凡夫俗子一样,
所以他想知道给一个整数n,求n!的在8进制下的位数是多少位。
输入描述:
第一行是一个整数t(0<t<=1000000)(表示t组数据)
接下来t行,每一行有一个整数n(0<=n<=10000000)
输出描述:
输出n!在8进制下的位数。

输入

3
4
2
5

输出

2
1
3

思路

单看测试样例的个数和n给的范围,用简单的取log10对数肯定是超时的,涉及到数学题那80%的可能性是考数论的,这里应该是用到了数论相关的知识。
这里用到了斯特林公式(Stirling’s approximation)
这是一条用来取n的阶乘的近似值的数学公式。一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特林公式十分好用,而且,即使在n很小的时候,斯特林公式的取值已经十分准确。
具体公式:n!≈√(2πn) (n/e)n,根号只作用于(2πn,后边的n是n次方。
我们把两边变取对数得
k-1 =log10(n!)= log10(√(2πn))+nlog10(n/e)
但是这里求出来的并不是我们想要的未知数,因为题目中要求我们求得是在8进制下的位数,由这个公式推导的原理我们可以得到,我们只需要用log8来取对数。但是C++的math库里是没有log8的,只需要用换底公式换成log10/log8就行了。
代码奉上

#include<bits/stdc++.h>
using namespace std;
int main()
{int N;cin >> N;while (N--){long res;int n;cin >> n;if (n <= 1)res = 1;elseres = (long)((log10(sqrt(4.0 * acos(0.0) / log10(8) * n)) + n * (log10(n) / log10(8) - log10(exp(1.0)) / log10(8))) + 1);cout << res << endl;}return 0;
}

C: The Mountain

题目描述

All as we know, a mountain is a large landform that stretches above the surrounding land in a limited area. If we as the tourists take a picture of a distant mountain and print it out, the image on the surface of paper will be in the shape of a particular polygon. From mathematics angle we can describe the range of the mountain in the picture as a list of distinct points, denoted by (x1,y1) to (xn,yn). The first point is at the original point of the coordinate system and the last point is lying on the x-axis. All points else have positive y coordinates and incremental x coordinates. Specifically, all x coordinates satisfy 0 = x1 < x2 < x3 < ··· < xn. All y coordinates are positive except the first and the last points whose y coordinates are zeroes. The range of the mountain is the polygon whose boundary passes through points (x1,y1) to (xn,yn) in turn and goes back to the first point. In this problem, your task is to calculate the area of the range of a mountain in the picture.

输入

The input has several test cases and the first line describes an integer t (1 ≤ t ≤ 20) which is the total number of cases. In each case, the first line provides the integer n (1 ≤ n ≤ 100) which is the number of points used to describe the range of a mountain. Following n lines describe all points and the i-th line contains two integers xi and yi (0 ≤ xi,yi ≤ 1000) indicating the coordinate of the i-th point.

输出

For each test case, output the area in a line with the precision of 6 digits.

样例输入

3
3
0 0
1 1
2 0
4
0 0
5 10
10 15
15 0
5
0 0
3 7
7 2
9 10
13 0

样例输出

1.000000
125.000000
60.500000

思路

很简单的一道题,难点难在了题目是英文,相当于求每个体形的面积(注意三角形不用单独列出来了,本身就是特殊的梯形)
代码奉上

#include<bits/stdc++.h>
using namespace std;
int main()
{int N;cin >> N;while(N--){int n;cin >> n;double a[n],b[n];cin >> a[0]>>b[0];double sum = 0.0;for (int i = 1; i < n;i++){cin >> a[i]>>b[i];sum += (b[i] + b[i - 1]) * (a[i] - a[i - 1]) / 2;}printf("%.6lf\n", sum);}
}

D: Sudoku

题目描述

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 4 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

输入

The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

输出

For each test case, print a line representing the completed Sudoku puzzle.

样例输入

.2738…1…1…6735…293.5692.8…6.1745.364…9518…7…8…6534.
…52…8.4…3…9…5.1…6…2…7…3…6…1…7.4…3.
end

样例输出

527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936

思路

这是一道数独的题,是一道深搜的题,同时还需要用到位运算优化,难度较大。
对于不能确定的位置,填充0-9,对于确定的位置,仅加入该数字。可以直接在输入串上记录答案,最后输出即可。
代码奉上

#include<bits/stdc++.h>
using namespace std;const int N = 9;int r[N], l[N], a[3][3];int ones[1 << N];
int mp[1 << N];char s[1000];int lobit(int x)
{return x & -x;
}int get(int x, int y)
{return r[x] & l[y] & a[x / 3][y / 3];
}bool dfs(int cnt)
{if (cnt == 0)return true;int minn = 100;int x, y;for (int i = 0; i < N; i++)for (int j = 0; j < N; j++)if (s[i * 9 + j] == '.'){int t = ones[get(i, j)];if (t < minn){minn = t;x = i;y = j;}}for (int i = get(x, y); i; i -= lobit(i)){int t = mp[lobit(i)];r[x] -= 1 << t;l[y] -= 1 << t;a[x / 3][y / 3] -= 1 << t;s[x * 9 + y] = '1' + t;if (dfs(cnt - 1))return true;r[x] += 1 << t;l[y] += 1 << t;a[x / 3][y / 3] += 1 << t;s[x * 9 + y] = '.';}return false;
}int main()
{for (int i = 0; i < N; i++)mp[1 << i] = i;for (int i = 0; i < 1 << N; i++){int k = 0;for (int j = i; j; j -= lobit(j))k++;ones[i] = k;}while (cin >> s, s[0] != 'e'){for (int i = 0; i < N; i++)l[i] = r[i] = (1 << N) - 1;for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)a[i][j] = (1 << N) - 1;int cnt = 0;for (int i = 0, k = 0; i < N; i++)for (int j = 0; j < N; j++, k++)if (s[k] != '.'){int t = s[k] - '1';r[i] -= 1 << t;l[j] -= 1 << t;a[i / 3][j / 3] -= 1 << t;}elsecnt++;//cout << cnt << endl;dfs(cnt);cout << s << endl;}return 0;
}

E: TYVJ 1042 表达式计算3

题目描述

给出一个表达式,其中运算符仅包含+,-,*,/,^要求求出表达式的最终值 在这里," /" 为整除 最终结果为正整数,数据保证不需要使用高精度!

输入

仅一行,即为表达式

输出

仅一行,既为表达式算出的结果 结果小于maxlongint,且整个计算的过程中,也不会超过maxlongint

样例输入

2^3+1

样例输出

9

思路

1,将数字和符号分别存放于数组中;
2,每次输入符号时,将前面所有小于或等于当前符号优先级的数据进行处理;
3,当最后一个数字输入时,从后往前对还存在的所有数据进行处理.
代码奉上

代码

代码片段:
1,优先级比较
int fun1(char ch)
{if(ch=='+')  return 0;else if(ch=='-') return 1;else if(ch=='*') return 2;else if(ch=='/') return 3;else if(ch=='^') return 4;return 0;}                                                  //各个符号所对应的值,与表格相对应int Judge[5][5] = {{0,0,-1,-1,-1},          //构建符号间优先关系表格{0,0,-1,-1,-1},          //从上往下,从左到右依次对应+,-,*,/,^{1,1,0,0,-1},            //1代表高于,0表示同级,-1表示低于{1,1,0,0,-1},{1,1,1,1,0}};
2,运算步骤
int fun(int a,int b,char c)
{int i,sum;if(c=='+')  sum = a+b;else if(c=='-') sum = a-b;else if(c=='*') sum = a*b;else if(c=='/') sum = a/b;else if(c=='^'){sum = 1;for(i = 0 ; i < b ; i++)                                    {sum *= a;}}return sum;
}
3,其他运算
char str[20],type[20];                      //str表示输入,type储存符号int num[20] = {0};                          //num用于储存数字,且初始化为0,方便多位数的储存int i,j = 0 , k = 0,len,t;                  //j表示数字个数,k表示符号个数int sum;                                    //sum表示计算得出的结果scanf("%s",str);len = strlen(str);for(i = 0 ; i < len ; i++){if(str[i]>='0'&&str[i]<='9'){num[j] += str[i] - '0';             //防止出现多位数字的情况,例:11+11,将11储存在一个数组元素中if(str[i+1]>='0'&&str[i+1]<='9')  num[j] *= 10;else j++;}else{while(Judge[fun1(str[i])][fun1(type[k-1])] <= 0&&k-1>=0)    //将前面所有小于或等于当前符号优先级的进行处理{k--;                                                    //符号出栈一位进行处理sum = fun(num[j-2],num[j-1],type[k]);                   //将数据进行处理j = j-2;                                                //数字出栈两位num[j++] = sum;                                         //将运算的结果接着储存num[j] = 0;                                             //一定要赋0,不然会对后面的数字储存造成影响}}if(str[i]<'0'||str[i]>'9')  type[k++] = str[i];if(i == len-1){for(t = k-1 ; t >= 0 ; t--)                                 //从后往前进行数据处理,因为后面符号的优先级可能会比前面的高{sum = fun(num[t],num[t+1],type[t]);num[t] = sum;}}}printf("%d\n",sum);return 0;

F: 逆序对

题目描述

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

输入

第一行,一个数n,表示序列中有n个数。(n≤40000)
第二行n个数,表示给定的序列。

输出

给定序列中逆序对的数目。

样例输入

6
5 4 2 6 3 1

样例输出

11

思路

这是一道第一眼看像是一道冒泡法逐个比较排序的题,但是用类似冒泡法排序非常的慢,时间肯定是超限了的,所以这里用的是sort函数的原理法,归并法,也就是二分的思想
这是一个简单的归并排序,大致意思就是把这一整段数字无限分割到最小的部分,然后对两个数组比较不断先取大后取小直到一方先取完,这就相当于把两个小的数组归并到一个大的数组里了,就这样分割之后再逐渐越来越大的合并,就是归并排序的思想。

代码奉上

代码

#include <bits/stdc++.h>
using namespace std;
int fx(int s[], int left, int m, int right)
{int i = left, j = m;int k[right - left + 1], in = 0, sum = 0, t = 0;while (i < m && j <= right){if (s[i] > s[j]){k[in++] = s[j++];t++;}if (s[i] <= s[j] || j == right + 1){sum += t * (m - i);k[in++] = s[i++];t = 0;}}while (i < m)k[in++] = s[i++];while (j <= right)k[in++] = s[j++];in = 0;for (int ii = left; ii <= right; ii++)s[ii] = k[in++];return sum;
}
int p = 0;
void f(int s[], int l, int h)
{if (l < h){int mid = (l + h) / 2;f(s, l, mid);f(s, mid + 1, h);p += fx(s, l, mid + 1, h);}
}
int main()
{int a[400010];int n;cin >> n;for (int i = 0; i < n; i++)cin >> a[i];f(a, 0, n - 1);cout << p << endl;
}

2021-06-02相关推荐

  1. 2021.06.02会解方程的计算器

    2021.06.02会解方程的计算器 (题目来源:) 题目描述 为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例: 4+3x=8 6a-5+1=2-2a -5+12y=0 ZL先生被主 ...

  2. 2021.06.02税收和补贴问题

    2021.06.02税收和补贴问题 (题目来源:洛谷-P1023) 题目描述 每样商品的价格越低,其销量就会相应增大.现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位 ...

  3. Mculover666的博客文章导航(嵌入式宝藏站)(2021.06.17更新)

    一.MCU系列 1. 开发环境 [Keil MDK](一)Keil MDK 5.28 的下载.安装.破解 [Keil MDK](二)Keil MDK中芯片器件包的安装 [Keil MDK](三)Kei ...

  4. 2021.06.03邮票面值设计

    2021.06.03邮票面值设计 题目描述 给定一个信封,最多只允许粘贴 N 张邮票,计算在给定 K(N+K≤15)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值 MAX ...

  5. 2021.06.06家庭财经系统制作(2)

    show tables; 查看数据库里有什么表命令. 碰到mysql软件问题.比想象的难缠. 用之前的方式打不开黑框(鼠标单击 mysql5.7 ccommand line Client),黑框一闪而 ...

  6. 【财经期刊FM-Radio|2021年02月23日】

    title: [财经期刊FM-Radio|2021年02月23日] 微信公众号: 张良信息咨询服务工作室 [今日热点新闻一览↓↓] 纳指跌超2%,科技股领跌,道指收涨,能源领衔走高,金银油铜高涨,伦铜 ...

  7. 前端面试每日3+1(周汇总2019.06.02)

    周汇总 2019.06.02 <论语>,曾子曰:"吾日三省吾身"(我每天多次反省自己). 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯, ...

  8. 【离散数学】 SEU - 28 - 2021/06/11 - Lattice and Boolean Algebra

    Discrete Mathematical Structures (6th Edition) 2021/06/09 - Lattice and Boolean Algebra Lattice and ...

  9. 2021.06.03合并石子+能量项链

    2021.06.03合并石子+能量项链 题目描述 在一个圆形操场的四周摆放 N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. ...

  10. 【离散数学】 SEU - 29 - 2021/06/16 - Review (in Chinese)

    Lattice and Boolean Algebra Boolen Algreba Atom Theorem: <⁣B,∧,∨,′,0,1⁣><\!B, ∧, ∨, ', 0, 1 ...

最新文章

  1. Android5.0之CoordinatorLayout的使用
  2. 关系型数据库之Mysql备份(五)
  3. 瑞星:ATM出现漏洞 银行:哪有这回事?
  4. CString与LPCWSTR的转化
  5. android高效加载网络图片
  6. [Everyday Mathematics]20150107
  7. 机器学习算法源码全解析(四)-人工神经网络关键核心知识点汇总
  8. 自动化运维工具SaltStack详细部署
  9. java jms clust,Geoserver 的 JMS Cluster modules(集群数据同步)
  10. java学习笔记2022.1.12
  11. linux软件包管理 pdf,vSphere Storage Appliance 安装和管理 PDF
  12. 操作系统 ——进程的状态与转换
  13. ubuntu 修该rm命令使删除文件到回收站
  14. 【Elasticsearch】Elasticsearch mapping 映射对象
  15. TensorFlow 1.9.0正式版来了!新手指南全新改版,支持梯度提升树估计器
  16. raid卡 4k 设置 linux,硬盘“大户”看过来,手把手教你组建 RAID 磁盘阵列
  17. 服务器系统日期,系统日期和服务器日期不一致
  18. Linux安装jdk详细步骤
  19. 数电(二)—分析/画逻辑电路图
  20. 提现微信和提现到支付宝

热门文章

  1. 移动硬盘打不开提示格式化怎么办?
  2. Atitit 艾提拉整理清明节的诗歌集合 清明节的特征 万物复苏 百草发芽 尝试从股市 其他外国诗歌集 得到清明的诗歌 约谈春天 歌颂春天 下雨 不见方三日、 夜来风雨声,花落知多少。(
  3. 密歇根州立大学联合领英提出基于AutoML的Embedding框架AutoDim
  4. java seo优化_java的seo优化-SEO技能未来发展前景
  5. 使用keycloak自定义SPI接入外部用户登录
  6. html 给word插入页眉和页脚,如何在Word插入页眉和页脚
  7. 计算机图形学立方体旋转代码,Flash AS教程:旋转立方体
  8. C# 透明窗体制作方法
  9. 如何优雅的(不花钱)获取一本技术图书
  10. MAC下串口助手合集