গ 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);}}
(বাইট গণনায় গণনা করা হয়নি এমন কয়েকটি নিউলাইনগুলি উপরে স্ক্রোল বারগুলি নির্মূল করার জন্য যুক্ত করা হয়েছে Yes হ্যাঁ, চূড়ান্ত নতুন লাইনটি গণনা করা হয়েছে))
কমান্ড লাইনে যুক্তি প্রত্যাশা করে এবং ধরে নেয় মানক আউটপুট ASCII কে গ্রহণ করে। রানটাইম হ'ল ও (বাইট আউটপুট সংখ্যা) = ও (এন * এন)।
না, আমি ব্যবহার করতে পারবেন না 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;
}
}
}
}
প্রমাণ
প্রোগ্রামটি সমস্যার সমাধান করে:
(প্রমাণ হিসাবে, সমস্ত অপারেটর এবং ফাংশনগুলিকে আসল গাণিতিক ফাংশন হিসাবে ^
ধরুন, কম্পিউটার অপারেশনগুলি যা তাদের আনুমানিক হয় না bit
স্পষ্টতার জন্য, আমি 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
, আমার প্রোগ্রামের জন্য একটি ইনপুট কেস আমার কোডের চেয়ে অর্ধেক সেকেন্ডেরও কম সময় ব্যয় করে তবে মোট প্রায় ৮০ সেকেন্ড সময় লাগে, যা আমি অনুমান করি যে বেশিরভাগই আউটপুটটিতে অবরুদ্ধ থাকতে হবে।