[COCI2015]ZGODAN

题目大意:
  给你一个数$n(n\leq10^1000)$,定义一个数是“美丽数”当且仅当这个数各个数位上的数奇偶性不同。
  求最接近$n$的“美丽数”,若有多个,则依次输出。

思路:
  贪心+高精度。
  首先找出$n$的第一个不符合要求的数位,从这一位开始贪心。
  后面几位要么是'8''9'交替(小于$n$的最大的“美丽数”),要么是'0''1'交替(大于$n$的最小的“美丽数”)。
  然后高精度减法减一下,比较哪个更接近即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 const int LEN=1002;
 4 char s[LEN],a[LEN],b[LEN],c[LEN],d[LEN],tmp[LEN];
 5 int len;
 6 inline void treat(char s[]) {
 7     for(register int i=0;i<len;i++) {
 8         s[i]^='0';
 9     }
10 }
11 int main() {
12     gets(s);
13     len=strlen(s);
14     treat(s);
15     a[0]=b[0]=s[0];
16     for(register int i=1;i<len;i++) {
17         if((s[i-1]&1)^(s[i]&1)) {
18             a[i]=b[i]=s[i];
19         } else {
20             if(s[i]!=0) {
21                 a[i]=s[i]-1;
22                 for(register int j=i+1;j<len;j++) {
23                     a[j]=a[j-1]&1?8:9;
24                 }
25             }
26             if(s[i]!=9) {
27                 b[i]=s[i]+1;
28                 for(register int j=i+1;j<len;j++) {
29                     b[j]=b[j-1]&1?0:1;
30                 }
31             }
32             if(s[i]==0) {
33                 treat(b);
34                 puts(b);
35                 return 0;
36             }
37             if(s[i]==9) {
38                 treat(a);
39                 puts(a);
40                 return 0;
41             }
42             for(register int j=len-1;j>=i;j--) {
43                 tmp[j]=s[j];
44             }
45             for(register int j=len-1;j>=i;j--) {
46                 if((signed char)tmp[j]<0) {
47                     tmp[j]+=10;
48                     tmp[j-1]--;
49                 }
50                 c[j]+=tmp[j]-a[j];
51                 if((signed char)c[j]<0) {
52                     c[j]+=10;
53                     tmp[j-1]--;
54                 }
55             }
56             for(register int j=len-1;j>=i;j--) {
57                 tmp[j]=b[j];
58             }
59             for(register int j=len-1;j>=i;j--) {
60                 if((signed char)tmp[j]<0) {
61                     tmp[j]+=10;
62                     tmp[j-1]--;
63                 }
64                 d[j]+=tmp[j]-s[j];
65                 if((signed char)d[j]<0) {
66                     d[j]+=10;
67                     tmp[j-1]--;
68                 }
69             }
70             treat(a);
71             treat(b);
72             for(register int j=i;j<len;j++) {
73                 if(c[j]<d[j]) {
74                     puts(a);
75                     return 0;
76                 }
77                 if(c[j]>d[j]) {
78                     puts(b);
79                     return 0;
80                 }
81             }
82             printf("%s %s\n",a,b);
83             return 0;
84         }
85     }
86     return 0;
87 }

 

posted @ 2018-02-06 10:02  skylee03  阅读(162)  评论(0编辑  收藏  举报