一道有意思的题目

        前几天编程班考试时发现第二题很有意思,大概是 NOIP 普及组第二题的难度,感兴趣的可以看看

problem2:有故障的打字机(typewrt)        

●题目描述

        一台打字机准备将 1到10^n 的数依次打出。在打印过程中,这台打字机出现了一个故障:数字“3”打不出来。因此,所有含有数字“3”的数都没有被正确地打出。试问没有被正确打出的数一共有多少个。

●输入格式

    输入一个正整数n。

●输出格式

    输出从1到 10^n 这些数中不能被正确打印的数的个数。

●输入输出样例

        #1  输入:

                2

        #1  输出:

                19

  ●规模限制

        各测试点1秒,你的程序将被分配32MB的运行空间,保证 n<=1000 。

思考时间......

    ●我的思路

        首先,看到数据范围就知道暴力肯定过不了,那么有什么其他办法呢?

        我们首先把 n 为不同值时的答案算出来,记录如下:

                n=1时:答案为10-9^{1}=1

                n=2时:答案为100-9^{2}=19

                n=3时:答案为1000-9^{3}=271

       数学好一点的小盆友们很快就能发现规律:ans_{n}=10^{n}-9^{n}

       到这一步,思路就基本出来了,只需要用高精度乘单精度算出10^{n}9^{n},再用高精度减法算出它们相减即可

        ●AC代码

#include<bits/stdc++.h>
using namespace std;
int a[1024],b[1024];//a[]==9^n,b[]=10^n
int n,lenb,lena;
void chen()
{
	for(int i=1;i<=lena;i++)
		a[i]*=9;
	int jw=0;
	
	for(int i=1;i<=lena;i++)
	{
		a[i]+=jw;
		jw=(a[i]/10); 
		a[i]%=10;
	}
	while(jw)
	{
		++lena;
		a[lena]=jw%10;
		jw/=10;
	}
}
void dec()//10^n-9^n;
{
	int len=max(lena,lenb);
	
	for(int i=1;i<=len;i++)//先减
		b[i]-=a[i];
	
	for(int i=1;i<=len;i++)//后处理进位  
	{
		if(b[i]<0)
		{
			b[i]+=10;
			--b[i+1]; 
		}
	}
	while(!b[lenb])
		--lenb;
}
int main(void)
{
	//freopen("typewrt.in","r",stdin);
	//freopen("typewrt.out","w",stdout);
	cin>>n;
	b[n+1]=1;//10^n
	lenb=n+1;
	a[1]=1;
	lena=1;
	while(n--)  chen();
	dec();
	for(int i=lenb;i>=1;i--)
		cout<<b[i];
	cout<<endl;
	return 0;
}

        完结撒花!!!dalao们有其他思路可以在评论区交流,Thanks♪(・ω・)ノ!

        ●题外话

                有没有dalao有推荐的讲述贪心算法的文章,蒟蒻想要深入了解一下这个算法,有的话私信我,谢谢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值