https://vjudge.net/problem/48715/origin
题意:给出必定含1689四个数字的字符串,随意交换位置构造出能被7整除的数。
分析:数学思维题。观察发现1689的排列与7的余数恰好是0...6,那么利用这个性质去与串中其他数字相补出能被7整除的数,把1689固定在后四位,把0独自提取出来,其他数字为一组,把它们的数值*10000后mod7,根据得到的余数选择相应的1689排列,最后把0放在末尾(对结果正确性没有影响)。
代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <algorithm> 5 #include <cstdlib> 6 #include <cstring> 7 #include <queue> 8 9 #define LL long long 10 11 using namespace std; 12 13 char s[1001000]; 14 char w[1001000]; 15 16 bool mark[11]; 17 18 int main() 19 { 20 21 memset(mark,false,sizeof(mark)); 22 23 LL top = 0,sum = 0,i,Zero = 0; 24 25 cin>>s; 26 27 int len = strlen(s); 28 29 for(i = 0;i < len; ++i) 30 { 31 if((s[i] == '1' || s[i] == '6' || s[i] == '8' || s[i] == '9') && mark[s[i]-'0'] == false) 32 { 33 mark[s[i]-'0'] = true; 34 } 35 else if(s[i] == '0') 36 { 37 Zero ++; 38 } 39 else 40 { 41 w[top++] = s[i]; 42 } 43 } 44 45 for(i = 0;i < top; ++i) 46 { 47 sum *= 10; 48 sum += (w[i]-'0'); 49 sum %= 7; 50 } 51 52 sum *= 10000; 53 sum %= 7; 54 55 for(i = 0;i < top; ++i) 56 { 57 printf("%c",w[i]); 58 } 59 60 switch(sum) 61 { 62 case 0:printf("1869");break; 63 case 6:printf("1968");break; 64 case 5:printf("1689");break; 65 case 4:printf("6198");break; 66 case 3:printf("8691");break; 67 case 2:printf("9861");break; 68 case 1:printf("8196");break; 69 } 70 71 while(Zero--) 72 { 73 printf("0"); 74 } 75 cout<<endl; 76 77 return 0; 78 }