校内OJ P1096 有错误的打字机

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

这道题目很显然,我们要想出来一种不重也不漏的方法

我是这样写的 我们从高到低枚举每一位

强制这一位选3,强制这一位前的全部不选,这一位后的随意

比如说对于第i位 那么对答案的贡献就是9^(i-1)*10^(n-i)

我们预处理出来ten[i]数组表示i个10连乘的结果,nig[i]表示i个9连乘的结果

就可以表示为nig[i-1]*ten[n-i]

PS:写这道题只当练习高精度了,我还是喜欢用结构体写高精度,美滋滋

校内OJ P1096 有错误的打字机校内OJ P1096 有错误的打字机
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 inline int read(){
 5     int x=0;int f=1;char ch=getchar();
 6     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 7     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 8     return x*f;
 9 }
10 struct node{
11     int sum[1010],len;
12 }nig[1010],ten[1010],ans;
13 inline node operator * (node x,int y){
14     node z;
15     memset(&z,0,sizeof(z));
16     int lenn=x.len;
17     for(int i=1;i<=x.len;i++){
18         z.sum[i]+=x.sum[i]*y;
19         if(z.sum[i]>=10){
20             z.sum[i+1]+=z.sum[i]/10;
21             z.sum[i]%=10;
22         }
23     }
24     if(z.sum[x.len+1]>0) lenn++;
25     z.len=lenn;
26     return z;
27 }
28 inline void operator *= (node &x,node y){
29     node z;
30     memset(&z,0,sizeof(z));
31     for(int i=1;i<=x.len;i++){
32         for(int j=1;j<=y.len;j++){
33             z.sum[i+j-1]+=x.sum[i]*y.sum[j];
34             if(z.sum[i+j-1]>=10){
35                 z.sum[i+j]+=z.sum[i]/10;
36                 z.sum[i+j-1]%=10;
37             }
38         }
39     }
40     if(z.sum[x.len+y.len]!=0) z.len=x.len+y.len;
41     else z.len=x.len+y.len-1;
42     x=z;
43 }
44 inline void operator += (node &x,node y){
45     node z;
46     memset(&z,0,sizeof(z));
47     int k=max(x.len,y.len);
48     for(int i=1;i<=k;i++){
49         z.sum[i]+=x.sum[i]+y.sum[i];
50         if(z.sum[i]>=10){
51             z.sum[i]-=10;
52             z.sum[i+1]++;
53         }
54     }
55     if(z.sum[k+1]!=0) z.len=k+1;
56     else z.len=k;
57     x=z;
58 }
59 inline void print(node x){
60     cout<<x.len<<endl;
61     for(int i=x.len;i>=1;i--){
62         cout<<x.sum[i];
63     }
64     cout<<endl;
65 }
66 void init(){
67     int n=read();
68     memset(ten,0,sizeof(ten));
69     memset(nig,0,sizeof(nig));
70     ten[0].sum[1]=1;ten[0].len=1;
71     for(int i=1;i<=n;i++){
72         ten[i].sum[i+1]=1;
73         ten[i].len=i+1;
74         
75     }
76     nig[0].sum[1]=1;nig[0].len=1;
77     for(int i=1;i<=n;i++){
78         nig[i]=nig[i-1]*9;
79         
80     }
81     memset(&ans,0,sizeof(ans));
82     for(int i=1;i<=n;i++){
83         node anss;
84         anss=nig[i-1];
85         anss*=ten[n-i];
86         ans+=anss;
87         //print(ans);
88     }
89     for(int i=ans.len;i>=1;i--){
90         printf("%d",ans.sum[i]);
91     }
92     cout<<endl;
93 }
94 int main(){
95     init();
96     return 0;
97 }
View Code