[LightOJ
来源:互联网 发布:python配置opencv3.0 编辑:程序博客网 时间:2024/06/05 05:38
链接:https://vjudge.net/contest/177082#problem/G
题目:
大意是讲通过公式H(n)计算出序列总和。
解题思路:
一开始我在网上搜了很多关于这道题的题解,但始终不是很懂为什么可以这样做,以及为啥要加上特判,到后面自己打表以后才慢慢懂一些。
为了更直观一些,打表结果如下:(左边数字是n/i可能数,右边是有多少个)
根据打表结果发现:1>发现有一些元素有很多个,比如"1",那么怎么快速计算出这些元素有多少个呢?
可以根据公式: 算出结果。(就是算出i到i+1之间有多少个数)
比如当n=10时,有:
2>每行元素的数量与sqrt(n)大小有关,但要根据条件判断是否减1,在仔细分析表后,发现似乎与n-sqrt(n)*sqrt(n)大小有关,如下:(灵魂画图,凑合着看)
如果n-sqrt(n)*sqrt(n)<sqrt(n)的话,那么说明元素种类是奇数,因为在计算和的时候是前后一起加的,所以最后要减去多加上的n/sqrt(n)。
代码如下:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <algorithm>using namespace std;typedef long long ll;#define MM(a) memset(a,0,sizeof(a))#define shutdown cin.sync_with_stdio(false);cin.tie(0);cout.sync_with_stdio(false);cout.tie(0)//int b[1001][1001];//打表专用//void init() {// for(int i=1; i<=100; i++) {// for(int j=1; j<=i; j++) {// b[i][j]=i/j;// }// }// for(int i=1; i<=100; i++) {// int temp=b[i][1],flag=1;// for(int j=1; j<=i; j++) {// if(b[i][j+1]==temp) flag++;// else{// cout<<temp<<":"<<flag<<" ";// temp=b[i][j+1];// flag=1;// }// }// cout<<endl;// }//}ll n;ll H(ll n) { ll res = 0; int i,sq=sqrt(n); for(i=1;i<=sq;i++){ res+=(n/i-n/(i+1))*i+n/i;//开头和尾部一起算 } if(n-sq*sq<sq)//如果元素的种类是奇数 res-=n/(i-1);//减去多加的 return res;}int main() { shutdown;// MM(b);// init(); int t; cin>>t; for(int i=1; i<=t; i++) { cin>>n; cout<<"Case "<<i<<": "<<H(n)<<endl; }}
阅读全文
0 0
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- [LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- Junit5的注解(Annotations)
- poj2187 Beauty Contest
- NIO读写文件示例
- 0041_First Missing Positive
- 8.15 老妹的难题 2700
- [LightOJ
- Redis的持久化-AOF
- CTU open Contest 2016 Tree Stands
- Illegalaccesserror 错误解决办法
- opencv之抓取视频每一帧并保存
- 第7章 IoC容器 I (Ioc-Bean) -- Spring4.3.8参考文档中文版
- Q-Learing结合神经网络对车联网的研究
- 2017.08.15【NOIP 普及组】模拟赛C组总结
- 响应式布局总结