PAT甲级 1049 Counting Ones (30 分)

The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (≤230).

Output Specification:

For each test case, print the number of 1’s in one line.

Sample Input:

12

Sample Output:

5

第一次做,算法思想很清晰,但是连测试用例都错误,后来再次读了一遍题目。我把题目理解成从0-n中包含1的数字的数量,而题目是求0-n中1的数量,题目差别在11我算一次他计算了2次。
出现这种题目读错的失误真是开头就错,恰好这两个算法差别不是很大,我能很快改回来,如果在考试上我岂不是凉凉?

算法分析
从例子入手吧, n=1234
从低位到高位进行分析。
1、个位为1,left_num=123,因此数量为123+1(0-123均可取)
2、十位为1,left_num=12, right_num=4, up_num=10,数量为(12+1)✖10
3、百位为1,left_num=1,right_num=34,up_num=100,数量为(1+1)✖100;
4、千位为1,left_num=0,right_num=234,up_num=1000,数量为1✖(234+1)+0✖1000=234;
5、然后全部相加即为结果。
核心状态代码为

			if(s_num[i]>'1')				
			ans+=(num_left+1)*right_up;
			else if(s_num[i]=='1')			
				ans+=(num_right+1)+num_left*right_up;	
			else
			ans+=(num_left)*right_up;               //向左边借位

以下为完整代码,可以自我体会一下

#include 
#include 
using namespace std;
int ans;
string s_num;
int num_up(int len)
{
	string s="";
	for(int i=0;i<len;i++)
		s+='0';
	s='1'+s;
	return atoi(s.c_str());		
}
int main()
{
	cin>>s_num;
	string::iterator it=s_num.begin();	
	while(it!=s_num.end()&&*it=='0') //首先去掉可能存在的前导0 
		s_num.erase(it);				
	for(int i=s_num.size()-1;i>=0;i--) //从地位到高位进行 
	{
		int num_left=0,num_right=0;
		string s_left,s_right;
			s_left="";
			s_right="";
			for(int r=0;r<i;r++)//左边 
				s_left+=s_num[r];
			for(int r=i+1;r<s_num.size();r++) //右边 
				s_right+=s_num[r];
			if(s_left!="")
			num_left=atoi(s_left.c_str());
			if(s_right!="")
			num_right=atoi(s_right.c_str());
			int right_up=num_up(s_right.length()); //右边数的上限 
			if(s_num[i]>'1')				
			ans+=(num_left+1)*right_up;
			else if(s_num[i]=='1')			
				ans+=(num_right+1)+num_left*right_up;	
			else
			ans+=(num_left)*right_up;               //向左边借位	
	}
	cout<<ans<<endl;	
	return 0;
}

你可能感兴趣的:(PAT,OJ试题)