题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/O
题意:
给定一个正整数N, 求的值
分析
已知
即
则结果为
即
根据gcd性质,若,则必有,即互质,
那么枚举的值,$ f(n)N/i$的欧拉函数值的和
代码:
1 | #include <iostream> |
题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/O
题意:
给定一个正整数N(N<4000000), 求G=∑i=1i<N∑j=i+1j≤Ngcd(i,j)的值
分析
已知f(N)=gcd(1,N)+gcd(2,N)+⋯+gcd(N−1,N)
即j=N,f(N)=∑i=1i<Ngcd(i,N)
则结果为f(2)+f(3)+f(4)+⋯+f(N)
即ans=∑i=2i≤Nf(i)
根据gcd性质,若gcd(k,n)=i,则必有gcd(k/i,n/i)=1,即k/i与n/i互质,
那么枚举i的值,$ f(n)等于N/i$的欧拉函数值的和
代码:
1 | #include <iostream> |
题目链接:
http://codeforces.com/problemset/problem/719/C
题目大意:
小明现在得知了自己的考试成绩是一个算上小数点共n位的小数,一共有t秒时间,每秒小明都可以对自己的小数点后的成绩进行一次四舍五入,问小明最大的成绩是多少
分析:
先找到小数点位置,因为四舍五入必须从小数点后进行,然后选择最靠近小数点的一位进位,如此t次,无法进位时退出,但此做法会超时,因为每次重新找要四舍五入的下标再进行进位会消耗很多时间,所以可以在进位的同时加上判断
代码:
1 | #include <cstdio> |
题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/V
题目大意:
读入一行数,求出所有数间最大的GCD值
分析:
根据GCD性质,N个数的GCD不大于N−1个数的GCD,所以最大GCD一定出现于两个数间,由于只有至多100个数,100组样例,O(N2)暴力,但是注意读入,一开始用字符串流一直WA,看了题解发现用C语言的字符读入就过了,玄学AC
代码:
1 | #include <iostream> |
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5584
题目大意:
在一个无限大的棋盘上,若起点为(x,y),则人每次可以选择向上走或者向右走,长度为lcm(x,y), 即走到(x+lcm(x,y),y)或者(x,y+lcm(x,y)),给定一个终点的坐标,求可以走到此处的合法起点有多少个
分析:
lcm(x,y)=gcd(x,y)x∗y
由于$x = pgcd(x,y) , y = qgcd(x,y) $ 所以lcm(x,y)=p∗q∗gcd(x,y),每次加上一个gcd(x,y)后,两坐标的gcd值不改变
根据此性质,我们可以列出方程,若向右走,则有
{x+lcm(x,y)=ay=b
代入可得
\begin{align*}x+x*b/gcd(x,y) =a \Longleftrightarrow x = \frac{a}{1+\frac{b}{gcd(x,y)}}\end{align*}
由于之前推得gcd(x,y)=gcd(a,b)
已知落点为(a,b),可以推得两种之前一步的位置,当gcd(x,y)=gcd(a,b) 或者$x<1 或y<1$时,即为退出条件,因此直接dfs即可
类似gcd,由于每一次x或者y都会减小为之前的1+gcd(x,y)b1≤21,所以这至多是一个指数级的递归深度,况且实际上远小于log2n,所以可以放心dfs
代码:
1 | #include<bits/stdc++.h> |
题目链接:
https://vjudge.net/contest/71746#problem/E
题目大意:
现有一个nk的矩阵A,以及一个kn的矩阵B,在模6域下,求得矩阵C = A*B,并对Cn∗n的每一个元素求和,输出结果
分析:
直接暴力对C矩阵做快速幂,用类会爆空间,会数组写比较繁琐,且可能超时,所以可以得到以下式子
Cn∗n=(A∗B)n∗n=A∗(B∗A)∗(B∗A)⋯∗(B∗A)∗B
即可写作
Cn∗n=A∗(B∗A)n∗n−1∗B
而B∗A是一个6*6的矩阵,对它求快速幂便很容易了
代码:
(因为调了好多遍,写的很丑,调试输出也很多,只要#define ONLINE即可不调试输出
1 | #include <cstdio> |
题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/X
题目大意:
给出一个二元一次方程ax+by+c=0,并给出两个范围[x1,x2]、[y1,y2],求x,y均在范围内的解的个数
分析:
1.a=0,b=0,c=0时,所有解均成立,共(y2−y1)∗(x2−x1)个解
2.a=0,b=0,c=0时,无解
3.a=0,b=0时,如果c不是a的倍数或c/a不在范围内,显然无解,反之[x1,x2]所有数均可
4.a=0,b=0时同理
先将方程转化为 ax+by=−c 扩展欧几里得解方程的标准形式
即c取反,如果c此时为负,则需对整个式子取反
如果此时a或b为负,需要对x或y的取值范围反转,变为[−x2,−x1]或[−y2,−y1]
将方程系数a,b代入exgcd(我用的是一个5参数的exgcd模板,中间的参数最后得到gcd(a,b))
然后比较c是否被gcd(a,b)整除,若不能,方程无解,若能x0=x∗c,y0=y∗c
通解为$ x = x0 + kb , y = y0 - ka 那么x1≤x0+kb≤x2$
−y2≤ka−y0≤−y1
解得$$\frac{x1}{b} - x0 \leq k \leq \frac{x2}{b} - x0$$
y0−ay2≤k≤y0−ay1
最后取并集即可 , 但是要注意如3.5≤k≤7.5 显然 左边需要向上取整
右边需要向下取整 使用floor 和ceil函数即可完成
1 | #include<iostream> |
题目链接:
http://acm.hust.edu.cn/vjudge/contest/76505#problem/L
题目大意:
每轮有N个球,M个篮筐,P的概率投中,投每个篮筐的概率相同,K轮之后进球数的期望为多少?
分析:
每一轮中,投中求数的期望互相独立,同时一轮进球数为E(X)=Np(二项分布期望),总进球数期望为E(X)=KNp,由于只是进球数且给定(M≥1),所以与篮筐数无关
1 | #include <cstdio> |
题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/T
题目大意:
读入两个01串,分别表示两个数X,Y
比如1101001表示 Fib = F0 + F3 + F5 + F6 = 1 + 5 + 13 + 21 = 40.
求这两个数的和,同样用01串表示结果 最后输出一个加法算式
如11101 1101
输出:
100101
注意:
1.输入的串可能有前导零
2.可能有0 0 这样的极端数据
3.输入的两个串也需要处理,样例里没有给出,但是题意里有
比如输入111应该输出1001
1 | #include<iostream> |
题目链接:
https://vjudge.net/contest/170743#problem/E
题目大意:
一个人要从x=0,x=1000,y=1000,y=0在第一象限包围出的矩形的左侧走到右侧,途中会遇到很多圆,不能走入圆内,求出发点和到达点y坐标最大的方案,若不可能输出IMPOSSIBLE
分析:
分析是否可行比较简单,从接触上边界的圆开始,dfs继续找所有与当前圆相交或者相切的圆,(内含理论上不必包含,但是这里包含并不影响正确性,而且代码逻辑更简单,所以没有特判),若发现接触下边界的圆,则说明不可能。
实际上这个过程用并查集也可以实现,设计一个up和down数组,表示该集合的最大坐标上界和下界,若两圆相交,则合并两圆的集合,最后fa[i]==i 的即是根,遍历所有根查找是否上界超出1000且下界低于0,即可判定可行性。
比较麻烦的是找出y坐标最大的解,实际上,画图可以发现,除了接触上界且接触左右界的圆集合,其他对答案都没有影响,可以通过"绕路"绕过,所以只要在dfs过程中,加上对当前圆与左右界是否相交的判断,然后算出最低交点的位置,与当前起点和终点分别取最小值即可。
代码:
1 | #include<stdio.h> |
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1075
题目大意:
先给出一些单词的英文翻译,然后给出一篇文章,存在标点,若文章中单词存在翻译,则转换成英文单词,若没有则不变,然后输出翻译后的文章
分析:
建立一个译文数组,在字典树中插入单词时,即可在单词结点处添加对应译文在数组中的下标,然后遍历文章,遇到标点与空格切分单词,特判最后末尾不是标点的情况,在树中查找是否出现过当前单词即可,存在即将单词的译文输出,否则输出原文,然后将当前遍历的标点直接输出
代码:
1 | #include<cstdio> |