सी 468
#include <stdlib.h>
#include <stdio.h>
#define a(s)fputs(s,stdout);
#define b(c)putchar(c);
int r;int z(char*s,int m){for(int i=0;i++<=m;)a(s)b(47)b(r+48)b(61)char*t=s;
while(*++t==48);a(t)while(m--)a(s)b(*s)b(10)}char x[10][60];
int main(int c,char**v){r=atoi(v[1]);int n=atoi(v[2]),q=10*r-1,d=0,p;
while(d++<9){p=r*d;char*y=x[d];do{p*=10;*y++=p/q+48;p%=q;}while(p!=r*d);}
d=1;p=q=0;while(n--){r==5&p<6?z(x[7],7*q+p++):(z(x[d],(r==5&d==7)?7*q+6:q),
++d>9?q+=d=1,p=0:0);}}
(बाइट गिनती में गिने नहीं गए कुछ नए किस्में ऊपर स्क्रॉल पट्टियों को खत्म करने के लिए जोड़े गए हैं। हां, अंतिम नई पंक्ति को गिना गया है।)
कमांड लाइन पर तर्क की अपेक्षा करता है, और मान लेता है कि मानक आउटपुट ASCII स्वीकार करता है। रनटाइम O (बाइट्स आउटपुट की संख्या) = O (n * n) है।
नहीं, मैं उपयोग नहीं कर सकता printf। यह बहुत अधिक समय लेता है और मेरे डेस्कटॉप पर मिनट सीमा पर कार्यक्रम को आगे बढ़ाता है। जैसा कि यह है, कुछ परीक्षण मामलों में लगभग 30 सेकंड लगते हैं।
एल्गोरिदम आउटपुट को स्ट्रिंग्स के रूप में मानता है, न कि संख्याओं के कारण, क्योंकि वे जल्दी से विशाल हो जाते हैं, और आउटपुट में मजबूत पैटर्न होते हैं।
कुछ असम्बद्ध:
#include <stdlib.h>
#include <stdio.h>
/* r is as in the problem description */
int r;
void show_line(const char* num, int repeats) {
for (int i=0; i <= repeats; ++i)
fputs(num, stdout);
printf("/%c=", '0'+r);
/* Assume the repeated num is a solution. Just move the first
digit and skip any resulting leading zeros. */
const char* num_tail = num;
++num_tail;
while (*num_tail=='0')
++num_tail;
fputs(num_tail, stdout);
while (repeats--)
fputs(num, stdout);
printf("%c\n", *num);
}
/* sol[0] is unused. Otherwise, sol[d] is the repeating digits in the
decimal representation of (r*d)/(10*r-1). */
char sol[10][60];
int main(int argc, char** argv) {
r = atoi(argv[1]);
int n = atoi(argv[2]);
int q = 10*r-1;
int d = 0;
/* Populate the strings in sol[]. */
while (d++<9) {
int p = r*d;
char* sol_str = sol[d];
/* Do the long division p/q in decimal, stopping when the remainder
is the original dividend. The integer part is always zero. */
do {
p *= 10;
*sol_str++ = p/q + '0';
p %= q;
} while (p != r*d);
}
/* Output the answers. */
d = 1;
int repeats = 0;
int r5x7_repeats = 0;
while (n--) {
if (r==5 && r5x7_repeats<6) {
show_line(x[7], 7*repeats + r5x7_repeats);
} else {
if (r==5 && d==7)
show_line(x[d], 7*repeats + 6);
else
show_line(x[d], repeats);
if (++d > 9) {
d = 1;
++repeats;
r5x7_repeats = 0;
}
}
}
}
सबूत
यह समस्या हल करती है:
(सबूत में, सभी ऑपरेटरों और कार्यों को वास्तविक गणितीय कार्य होने के लिए लें, न कि कंप्यूटर संचालन जो उन्हें अनुमानित करते हैं। ^घातांक को दर्शाते हैं, बिटवाइज़ एक्सर नहीं।)
स्पष्टता के लिए, मैं ToDecएक संख्या का उपयोग दशमलव अंकों के अनुक्रम के रूप में संख्या लिखने की सामान्य प्रक्रिया का वर्णन करने के लिए करूँगा । इसकी सीमा क्रमबद्ध टुपल्स का सेट है {0...9}। उदाहरण के लिए,
ToDec(2014) = (2, 0, 1, 4).
एक सकारात्मक पूर्णांक के लिए n, L(n)दशमलव प्रतिनिधित्व में अंकों की संख्या को परिभाषित करें n; या,
L(n) = 1+floor(log10(n)).
एक सकारात्मक पूर्णांक kऔर एक गैर-नकारात्मक पूर्णांक nके लिए L(n)<k, Rep_k(n)दशमलव अंकों के सामने शून्य जोड़कर प्राप्त वास्तविक संख्या को परिभाषित करें n, यदि आवश्यक हो kतो कुल अंक प्राप्त करें , और फिर kदशमलव बिंदु के बाद उन अंकों को दोहराते हुए । उदाहरण के लिए
Rep_4(2014) = .201420142014...
Rep_5(2014) = .020140201402...
गुणा करना दशमलव बिंदु Rep_k(n) * 10^kसे nपहले के अंक और (शून्य-पेड) अंकों nको दशमलव बिंदु के बाद अनंत रूप से दोहराया जाता है। इसलिए
Rep_k(n) * 10^k = n + Rep_k(n)
Rep_k(n) = n / (10^k - 1)
एक सकारात्मक पूर्णांक को देखते हुए r, मान लीजिए xकि समस्या का समाधान है, और
ToDec(x) = ( x_1, x_2, ..., x_k )
जहां x_1 != 0और k = L(x)।
एक समाधान होने के लिए, xका एक बहु है r, और
ToDec(x/r) : ( x_2, x_3, ..., x_k, x_1 ).
Rep_kफ़ंक्शन को लागू करना एक अच्छा समीकरण देता है:
10*Rep_k(x) = x_1 + Rep_k(x/r)
ऊपर से इसके बंद रूप का उपयोग करना,
10x / (10^k - 1) = x_1 + x / r / (10^k - 1)
x = x_1 * r * (10^k-1) / (10r - 1)
x_1सेट में होना चाहिए {1 ... 9}। rसेट में होना निर्दिष्ट किया गया था {2 ... 9}। अब एकमात्र प्रश्न यह है कि सकारात्मक पूर्णांक देने के kलिए उपरोक्त सूत्र किन मूल्यों के लिए है x? हम rव्यक्तिगत रूप से प्रत्येक संभावित मूल्य पर विचार करेंगे ।
जब r= 2, 3, 6, 8, या 9 10r-1, क्रमशः 19, 29, 59, 79 या 89 है। सभी मामलों में, भाजक p = 10r-1प्रमुख है। अंश में, केवल 10^k-1एक ही हो सकता है p, जो तब होता है
10^k = 1 (mod p)
समाधानों के सेट को अतिरिक्त और घटाव के तहत बंद किया जाता है जिसके परिणामस्वरूप नकारात्मक संख्या नहीं होती है। तो सेट में कुछ सामान्य कारक के सभी गुणक शामिल हैं, जो कम से कम सकारात्मक समाधान भी है k।
कब r = 4और 10r-1 = 39कहां; या जब r = 7और 10r-1 = 69, हर 3 बार एक अलग प्राइम है p=(10r-1)/3। 10^k-1हमेशा 3 का एक गुणक होता है, और फिर से अंश में कोई अन्य कारक एक से अधिक नहीं हो सकता है p, इसलिए फिर से समस्या कम हो जाती है
10^k = 1 (mod p)
और फिर समाधान सभी के लिए कम से कम सकारात्मक समाधान के गुणक हैं k।
[तैयार नहीं...]
gprof, मेरे कार्यक्रम के लिए एक इनपुट मामले मेरी कोड में दूसरी छमाही की तुलना में कम एक खर्च करता है, लेकिन लगभग 80 सेकंड कुल लेता है, जो मैं ज्यादातर उत्पादन पर अवरुद्ध होना चाहिए मान।