noj [1475] Bachelor (找1的个数)
[1475] Bachelor
- 时间限制: 1000 ms 内存限制: 65535 K
- 问题描述
- 炎热的暑期集训就要结束了,在这短短的20天,大家都很努力,因为很多都是光棍嘛。balabala 所以 Marknoon 先森一直耿耿于怀,毕竟他也是单身嘛。 有一天,Marknoon 先森看着一串数字,发现了那个跟他同命相连的数字1,所以他就开始无聊起来,想知道从数字1到数字N,一共出现了几个1。 例如N=12,则1的个数为5,出现1的数字分别为1,10,11,12。
- 输入
- 输入一个数N(1 <= N <= 2147483647)。
- 输出
- 输出从1到N中所有数字里出现 1 的个数。
- 样例输入
3
13
123- 样例输出
1
6
57- 思路:
解法1:按位置计算,即分别计算个位,十位,百位,千位 。。。的 1 出现的次数,然后将他们的个数和输出
这里以 2145 为例进行说明: 个位为 1 的情况 : _ _ _ 1 横线部分 可以是 000 到 214 的任意数字 所以个位 一共有 215个 1 ------- (214 + 1)
十位为 1 的情况: _ _ 1 _ 横线部分 可以是 000 到 219 的任意数字 十位 一共有 220 个 1 ------- (21 +1)*10
百位为 1 的情况: _ 1 _ _ 横线部分 可以是 000 到 245 的任意数字 百位 一共有 246 个 1 ------ 2 * 100 +45 +1
- 千位为 1 的情况: 1 _ _ _ 横线部分 可以是 000 到 999 的任意数字 千位 一共有 1000 个 1 ------ (0 + 1)* 1000
- 当然 还有 为 0 的情况 如果是 2105 的话 则 有 21* 10 ---- 十位 有 210 个 1
- 规律应该可以找到了吧!!!
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector> using namespace std; int getNum(int *a,int i,int j) //得到a数组里面[i,j]区间构成的数
{
int sum=;
for(;i<=j;i++) sum=*sum+a[i];
return sum;
} int main()
{
char str[];
int a[];
__int64 p[]={,,,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12};
while(~scanf("%s",str))
{
int len = strlen(str);
int i,left,right;
for(i=;i<len;i++) a[i]=str[i]-'';
__int64 sum = ;
for(i=;i<len;i++)
{
left = getNum(a,,i-);;
if(a[i]>)
{
sum+=(left+)*p[len--i]; //如果数字大于1 则用左边 a[0,i-1] 构成的数 加1 乘上 10的(右边位数)次方
}
else if(a[i]==)
{
right = getNum(a,i+,len-);
sum+=left*p[len--i]+right+; //如果数字等于1 则用左边 a[0,i-1] 构成的数 乘上 10的(右边位数)次方 后 加上 右边a[i,len-1] 构成的数 再加上1
}
else if(a[i]==)
{
sum+=left*p[len--i]; //如果数字等于0 则用左边 a[0,i-1] 构成的数 直接乘上 10的(右边位数)次方
}
}
printf("%I64d\n",sum); }
return ;
}解法二:先写断暴力代码测试用:
- 找到规律输 9:1
- 99:20
- 999:300
- 9999:4000
- 99999 : 50000
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
int main()
{
int i;
__int64 a[]={,};
int b[]={};
char str[];
a[]=;
for(i=;i<;i++)
{
int cnt=;
if(i%==)
cnt++;
if(i/==)
cnt++;
b[i]+=b[i-]+cnt;
}
__int64 temp=; __int64 pow[]={,,,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12}; for(i=;i<=;i++)
{
a[i]=i*pow[i-];
} while(~scanf("%s",str))
{
int len=strlen(str);
__int64 s=;
for(i=;i<len;i++)
{
temp = str[i] - '';
s=*s+temp;
}
__int64 sum=;
for(i=;i<len-;i++)
if(str[i]!='')
{
int p=len-i;
if(str[i]=='')
{
s=s%pow[p-];
sum+=a[p-]+s+;
}
else
sum+=pow[p-]+a[p-]*(str[i]-'');
}
sum+=b[s%];
printf("%I64d\n",sum);
}
return ;
}
noj [1475] Bachelor (找1的个数)的更多相关文章
- NBUT [1475] Bachelor
[1475] Bachelor http://acm.nbut.cn:8081/Problem/view.xhtml?id=1475 时间限制: 1000 ms 内存限制: 65535 K 问题描述 ...
- 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数
找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...
- search for a range(找出一个数在数组中开始和结束位置)
Given an array of integers sorted in ascending order, find the starting and ending position of a giv ...
- 找出n个数中出现了奇数次的两个数
如果是找只出现了奇数次的一个数, 那么我们从头异或一遍就可以. 那么如何找出现了奇数次的两个数呢? 首先我们还是从头异或一遍, 然后结果肯定不为0, 对于异或出来的结果, 如果这个数的某一位是1, 说 ...
- 3sum(从数组中找出三个数的和为0)
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- 找出N个数中最小的k个数问题(复杂度O(N*logk))
这是一个经典的算法题,下面给出的算法都在给定的数组基础上进行,好处时不用分配新的空间,坏处是会破坏原有的数组,可以自己分配新的空间以避免对原有数组的破坏. 思路一 先直接排序,再取排序后数据的前k个数 ...
- SDUT OJ 1221 亲和数 (找出某个数n所有的因子数,只需要暴力:2->sqrt(n) 即可 )
亲和数 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 如果a的因子和等于b,b的因子和等于a,且a≠b,则称a,b为亲和数对. ...
- 【算法学习笔记】Meissel-Lehmer 算法 (亚线性时间找出素数个数)
「Meissel-Lehmer 算法」是一种能在亚线性时间复杂度内求出 \(1\sim n\) 内质数个数的一种算法. 在看素数相关论文时发现了这个算法,论文链接:Here. 算法的细节来自 OI w ...
- 找大于等于一个数的最小的2^n
最近看hashmap源码时,发现给定初始capacity计算threshold的过程很巧妙. 1 static final int tableSizeFor(int cap) { 2 int n = ...
随机推荐
- iOS-label出现未知边框线的bug
在前段时间碰到了一个问题 label上出现了一个位置的右边框 仔细查看代码发现没有指定边框 而且奇怪的是只显示右边框 其他边框没有显示 需求效果图: 实际效果图: 结构图: 通过查看结构图 可 ...
- ubuntu on win VS ubuntu(virtual box)VS Cygwin
执行命令粗略估计执行时间: date --rfc-3339='ns';seq 100000000 | grep 8 | wc -w; date --rfc-3339='ns' ubuntu 14.04 ...
- c语言面试题之sizeof
c语言面试题之sizeof */--> c语言面试题之sizeof Table of Contents 1. sizeof 1 sizeof sizeof是c语言中判断数据类型或者表达式的长度符 ...
- docker 错误
docker search ubuntuGet http:///var/run/docker.sock/v1.20/images/search?term=ubuntu: dial unix /var/ ...
- [转].net连oracle的问题及方法折腾总结 连接字串
本文转自:http://www.th7.cn/Program/net/201305/138265.shtml 对oracle不算熟,对.net结合oracle开发项目也只做过一个.最近换了新电脑,装了 ...
- Servlet线程安全问题
Servlet采用单实例多线程方式运行,因此是线程不安全的.默认情况下,非分布式系统,Servlet容器只会维护一个Servlet的实例,当多个请求到达同一个Servlet时,Servlet容器会启动 ...
- c# 远程监控(2) 摄像头调研及模拟
经过N多调研,最终选择了OpenCV(Emgu CV) ** 至于DirectShow, OpenCV等等其他大家可以百度,在这里我就不再赘述 环境:vs2010 vs2012 vs2013均可 Op ...
- scala学习笔记:各种奇怪的写法
Unit函数的定义: def foo()={println("hi")} 等号可以省略: def foo(){println("hi")} update方法: ...
- Html5时钟的实现
最近准备把自己的博客装修一下,首先,先为自己设计一个时钟吧,希望博客园能够尽快发放给我使用js的权限! 自从看见了苹果设计的那款因为侵权而赔钱了时钟,我就决定我的时钟一定是要参考这个来设计了! 不得不 ...
- Oracle PL/SQL 事物处理 银行转账
Oracle数据库中的事务处理:添加,修改,删除时需要使用事务处理(显示事务). 1.事务的分类显示事务(添加,修改,删除)和隐式事务(除了添加,修改,删除). 2.事务的执行方式:自动提交(jdbc ...