[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 }