Page 3 Please explane what is K. What it means K=10? Ok now I get it. Why then did not explain to others? Bin: K = 2, [0,1] Oct: K = 8, [0,1,2,3,4,5,6,7] (или [0..7]) Dec: K = 10, [0,1,2,3,4,5,6,7,8,9] (или [0..9]) Hex: K = 16, [0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F] (или [0..F]) То есть список цифр из которых может состоять К-ичное число = [0..K-1]. PS: В задаче K не > 10. Значит буквы не участвуют. 1010230 is a valid 7-digit number; 1000198 is not a valid number; -------------[WHY??] 0001235 is not a 7-digit number, it is a 4-digit number. so if N=3 K=10: 100 can't be a valid number? (Because it has two continuous zeros ?) but 101 is a valid number, right? Please provide me with more examples... We define a number to be valid if its K-based notation doesn’t contain two successive zeros. 1000198 has three successive zeros,so it is invalid. Of course,100 is invalid where 101 is valid. I think l have solved this problem,but i got WA on test #2. For my solution replacing integer 32-bit with 64-bit integer helped, and all tests passed. There is a 32-bit integer overflow in test #2. #include<stdio.h> int power(const int a,const int b) { int k=0,num=1; for(k=0;k<b;k++) { num=num*a; } return num; } int foc(int a) { if(a==1) { return 1; } else { return foc(a-1)*a; } } int arr(int a,int b) { if(!b) { return 1; } else { return foc(a+b)/(foc(a)*foc(b)); } } int main(void) { int n=0,k=0,i=0,sum=0; scanf("%d",&n); scanf("%d",&k); for(i=0;n-i>=i;i++) { if(!i) { sum=sum+power(k-1,n); } else if(i==1) { sum=sum+(n-1)*power(k-1,n-1); } else { sum=sum+arr(i,n-2*i)*power(k-1,n-i); } } printf("%d\n",sum); return 0; } test results: N K result 3 10 891 4 10 8829 5 10 87480 6 10 866781 7 10 8588349 8 10 85096170 2 2 2 3 8 441 5 9 50688 I'll appreciate it if you find the dead test and point my bug out,thank you! By the way,I get the WA at test#2. Edited by author 16.11.2010 20:38 import java.util.Scanner; import java.util.Arrays; public class T_1009 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] m = new int[n+1]; // Dynamic m[1] = k-1; m[2] = k*(k-1); for (int i = 3; i <=n; i++) { m[i] = (m[i-1]+m[i-2])*(k-1); } System.out.print(m[n]); } } for k = 2, n = 2 Enigma [UB of TUIT] programm write 3, but right answer 2, because: 10 11 f(n) = f(n - 1) * k - f(n - 2) why it's wrong? as i understand, f(n - 2) is how many zero-ending numbers in f(n - 1). am i wrong? n , k 1. if ( n = 0 ) , then answer = ( 1 ). 2. if ( n = 1 ) , then answer = ( k-1 ). 3. else answer(n) = ( k-1 ) * ( answer(n-1,k) + answer(n-2,k) ). Edited by author 20.06.2010 04:04 n>=2 !!! Okay, I'll join to Captains Obvious. You can find an answer with O(1) memory and O(logN) time. Can you explain this algo? Really interesting to know better one. Thx. Okay, I'll join to Captains Obvious. You can find an answer with O(1) memory and O(logN) time. Sure, you're welcome. Okay, we're already know, that the answer can be found reccurently: F(N) = (K-1)*(F(K-1)+F(N-2)), where F(0) = 1, F(1) = K-1. We see, that the {F(N)} sequence is very similar to Fibonacci's one and can assume some facts. I see two different approaches to solve the problem. 1) First way is to build characteristic equation, solve it and get an exact formula for F(N). I didn't try this way, because I foresaw some problems with precision and float calculations. If you're interested, you can turn to this article as a manual: http://www.intuit.ru/department/algorithms/algocombi/8/2.html 2) I assumed, that method with fast matrix exponentiation will work as well as for Fibonacci's numbers. Just consider a matrix: L(N) = {{F(N+1), F(N)}, {F(N), F(N-1)}}. Let's try to find such R, that L(N)*R = L(N+1). If you write down this information, you'll easily see, that R = {{K-1, 1}, {K-1, 0}}. So all you need is to find L(1)*R.pow(N-2). Hope this information was helpful, I'm not sure it is the best way to describe an approach though. :-) Edited by author 16.08.2010 13:34Actually, I implemented only O(N)-solution before. Today I wrote a code for a fast exponentiation, but (it seems I don't know java well) my time increased in #1013, where BigInteger is needed. Strange. :-) Artem Khizha [DNU] Thx for explanations and idea! I got it! Really nice approach with matrixes! #include <iostream> using namespace std; unsigned long stepen(unsigned long K,unsigned long N) { unsigned long i, result=1; if (N<0) return 0; else { i=1; for(; i<=N; i++) result*=K; return result; } } int main() { unsigned long N, K, i, result; cin>>N; cin>>K; result=stepen(K, N)-(stepen(K,N-2)+stepen(K, N-1)-1); cout<<result<<endl; //system("Pause"); return 0;
} WA #2. Why? >>dima11221122 Firstly, I came up with something like that and got WA2 too. N = (k-1)^n + n(k-1)^(n-1) - that formula looks pretty alright; but it isn't. It assumes there can't be more than one zero in the number, while there obviously can. The actual answer is something like that - N = (k-1)^n + n * (П(i=1 to min(k,n)) of (k-i)^(n-1)) and i think it's anyways easier to solve that like original poster did. Btw, your code is sooooo bad; u might wanna do something about that. Edited by author 26.11.2011 06:42 n , k 1. if ( n = 0 ) , then answer = ( 1 ). 2. if ( n = 1 ) , then answer = ( k-1 ). 3. else answer(n) = ( k-1 ) * ( answer(n-1,k) + answer(n-2,k) ). Edited by author 20.06.2010 04:04 I am not sure, how the number of zero digit numbers (of course, without two zeros in it) become 1. Edited by author 29.03.2012 02:38Can anybody tell me where can i get some info about this topic(k-based numbers), I really don't get from where cames this recurrent formula? Greetings How can we get valid n-digit number? Trivially, we can append each of (k-1) possible digits (k digits except for 0) to the front of each of (n-1)-digit valid numbers. But we can also form valid number this way: append 0 to the front of (n-2)-digit valid number, and then append (k-1) possible digits, as in the first case. This gives us F(n) = (k-1)*F(n-1)+(k-1)*F(n-2), where F is the function to yield the amount of valid n-digit numbers. I'd recommend you to ensure this yields only the valid numbers, think why can't it produce duplicates, and whether other means to construct valid numbers are possible. Then you follow Artem Khizha's [DNU] recipe and get an AC (= Edited by author 08.08.2012 19:05 > Amir Aupov [MIPT] I like your explanation. I approached the construction of N digit numbers from N-1 digit numbers in the typical way of constructing numbers: multiply N-1 digit number by base, and add in the new digits to the units position. This has the benefit of being clear and natural, so we can be sure that we're not missing any numbers. It has the disadvantage that you must track numbers that end in zero separately from those that don't. But this is still quite simple: Z(n): # of valid numbers ending in zero NZ(n): # of valid numbers not ending in zero Z(2) = k - 1 NZ(2) = (k - 1) * k - (k - 1) (total number of valid 2-digit numbers, minus those that end in 0) then, Z(n) = NZ(n - 1) NZ(n) = (Z(n-1) + NZ(n-1)) * (k - 1) Compute Z(n) and NZ(n) iteratively (DP), and then output F(n) at the end F(n) = Z(n) + NZ(n) HI David, The problem statement language is confusing. A "k-based number" is a number represented in base "k", that's all. #include<iostream.h> #include<math.h> int ji(int n); int main() { int k,n,m,c,a; int d=0; cin>>n>>k; if((k>=2&&k<=10)&&n>=2&&(n+k)<=18) { m=0; if(n%2==1) while(m<(n+1)/2) { c=ji(n-m); a=ji(m); d=d+int(pow(k-1,n-m-1)*c/a/ji(n-m-m)); m++; } else while(m<=(n+1)/2) { c=ji(n-m); a=ji(m); d=d+int(pow(k-1,n-m-1)*c/a/ji(n-m-m)); m++; } cout<<(k-1)*d<<endl; } return 0; } int ji(int n) { if(n==0) return 1; else return n*ji(n-1); } import java.util.Scanner; public class Kb_numb { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int i,n,k; int[] F=new int[20]; Scanner in=new Scanner(System.in); n=in.nextInt(); k=in.nextInt(); F[0]=k-1; F[1]=k*F[0]; for(i=2;i<n;i++){ F[i]=(F[i-1]+F[i-2])*(k-1); } System.out.print(F[n-1]); } } #include<iostream.h> int power(int a, int b) { if(b==0) return 1; if(b%2==0) return power(a, b/2) * power(a, b/2); if(b%2!=0) return power(a, b/2) * power(a, b/2) * a; } int main() { int n, k; cin>>n>>k; int a, b; a=power(k, n-1) * (k-1); b=power(2, n-1); cout<<a-b+n<<endl; return 0; } I think that the answer of this problem is (k-1)*k^(n-1)-2^(n-1)+n why it is wrong i don't understand. Because it is not working!!!!!!!!!!!!!!!!!!!!! yes it doesn't! =) yes it doesn't! =) Don't use alien wrong solution! I think the easiest way is to precalculate trough Brute Force a table containing the values, hard-code it, and simply give back A[ n ][ k ] :D Plus, the solution will run fast as hell XD You can do that with problems that have small values of n and k, but it'll run just as fast with a good algorithm. If you did it that way you have not actually solved the problem. for n = 1, k
the answer is : k while many programs give: k-1 but there is no such test data and also N=6,K=10 N=7,K=10 N=6,K=2 N=5,K=10 the answer is 87480 N=6,K=10 the answer is 866781 N=7,K=10 the answer is 8588349 N=6,K=2 the answer is 13 my program has been accepted I have solved this problem,but I got WA on test #2.When n=6,k=10 I get answer 866781 and others tests I get right answer.What is the test #2??????????????? N=5,K=10 the answer is 87480 350975 350974 350973 350971 350970 350967 350966 350965 350959 350958 350957 350955 350954 350943 350942 350941 350939 350938 for n = 6 , k = 2 this values are true more than 13 You are not right because k = 2 => all numerals < 2. Ok? And now I show you this 13 numbers: 111111 111110 111101 111011 110111 101111 111010 110110 110101 101110 101101 101011 101010 sorry for my English Edited by author 19.08.2020 13:21 Edited by author 19.08.2020 13:21 my code crashed on 1 test {*****************} type integer=longint; var n,k:integer; obr:string; str:string; otv:int64; procedure p(s:string); var i,l:integer; begin l:=length(s)-1; if l=n then begin inc(otv); writeln(s); exit; end; if l>n then begin exit; end; for i:=1 to k do begin if (s[l]='0')and(obr[i]='0') then continue; if (l=0)and(obr[i]='0') then continue; p(s+obr[i]); end; end; begin assignfile(input,'in.txt'); reset(input); assignfile(output,'out.txt'); rewrite(output); readln(n); readln(k); otv:=0; obr:='0123456789'; str:='_'; p(str); writeln(otv); end. {*******************} Please help! #include <stdio.h> typedef unsigned long int INT; void main() { INT N,K,i; scanf("%lu%lu",&N,&K); INT *F=new INT[N]; F[0]=K-1; F[1]=K*F[0]; for(i=2;i<N;i++) F[i]=(K-1)*(F[i-1]+F[i-2]); printf("%lu",F[N-1]); } help me, i can't find error in my algo. for (n = 3, k = 10) we have 1 case x00, where x can take (k-1) digits (anyway first digit can take k - 1) so answer is 9*10^2 - 9 = 891 - right! for (n = 4, k = 10) we have 2 cases: x00y - y can take k digits - 9*10 xx00 - 9*9 answer - 9*10^3 - 90 - 81 = 8829 - right for(n = 5, k = 10) we have 3 cases x00yy (9*10^2) xx00y (9^2*10) xxx00 (9^3) we have 87561, but right answer is 87480 Edited by author 23.12.2007 15:29 for(n = 5,k = 10) You are wrong Right answer x00yy(9*10^2) xx00y(9^2*10) xyx00(9^2*10) //!!!xYx00 87480 Here are my tests not very important but please abswer them too. 2 2> 2 3 2> 3 4 2> 5 5 2> 9 6 2> 17 7 2> 33 16 2> 16385 more important tests for me: 2 10> 90 3 10> 891 4 10> 8829 5 10> 87561 6 10> 869049 7 10> 8631441 8 10> 85782969 Thanks very much. No. some of them are wrong.I mean tests are ok but answers are not. Here are the true ones: 2 2 > 2 3 2 > 3 4 2 > 5 5 2 > 8 6 2 > 13 7 2 > 21 16 2 > 1597 2 10> 90 3 10> 891 4 10> 8829 5 10 > 87480 6 10 > 866781 7 10 > 8588349 8 10 > 85096170 спасибо спасибо то есть, thanks. =) I've got AC. I found a new kind of algo for this problem.I wish if someone could tell me if it's good or bad. I got wa on test 2 .Bad algo or bad implementation? !!11.First we find numbers made from n-1 numbers that can begin with 0, but don't have 2 zeros one after the other. We find them like this.for(i=0;i<=n-2;i++) we put the two zeros on i position and now we have 2 numbers one in the left of 2 zeros and one in the right.the number of numbers in right is k^((n-1)-2-i).In left we do !!11. for i-1.(if n<=4)else the number is (k-1)*k^(n-1-2-i)*(k-1)^(i-1) I've too new algo, but I've CRASh(over flowler steck-check) here is my code, function f(n, k : integer) : integer; begin f := 0; if n = 2 then f := 0 else begin if n = 3 then f := k-1 else if n > 3 then f := TRUNC(f(n-1, k)+ (n-2)*exp((n-2)*ln(k-1))); end; end; begin read(n, k); s := TRUNC((k-1)*exp((n-1)*ln(k)) - f(n, k)); write(s); end. first I find how many numbers have 00; for example: k = 6; n = 3 ---- 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 5 n = 4 ---- 0 1 2 3 4 5 5*6+5*5 n = 5 ---- 0 1 2 3 4 5 5+25+25+125+125+125 n = 6 ---- 0 1 2 3 4 5 5+25+25+125+125+125+625+625+625+625 n = 7 ---- 0 1 2 3 4 5 5+25+25+125+125+125+625+625+625+625+3125+3125+3125+3125+3125 f = f(n-1)+(n-2)*exp((n-2)*ln(k-1)); 4 = 5 + 2*5*5 5 = 55 + 3*5*5*5 6 = 330+4*5*5*5*5 ... then k^n all numbers k^(n-1) all numbers till n digits then we've f=k^n-k^(n-1)-(n-2)*(k-1)^(n-2); i can't find what's wrong in this here is code of program! var n, k : integer; begin read(n, k); n := TRUNC(k*exp((n-1)*ln(k-1))); writeLn(n); end. if k = 10 and n = 3 then we can write that: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 and 3 number maybe one of them. first number maybe all of them, second 9. third 9 too, Where is wrong? This is MY SOLVe!!! program MEGA; {$APPTYPE CONSOLE} uses SysUtils; var i,n,k:integer; a:array[1..100] of int64; m:int64; begin read(n,k); if n=2 then begin writeln((k-1)*k); halt(0); end; if n=3 then begin writeln((k-1)*k*k-k+1); halt(0); end; a[3]:=k-1; m:=k-1; for i:=4 to n do begin m:=m*(k-1); a[i]:=a[i-1]+(i-2)*m; end; m:=k-1; for i:=1 to n-1 do m:=m*k; writeln(m-a[n]); end. I had a wrong answer in test #2 due to integer overflow. Replacing 32-bit integers with 64-bit integers helped and all tests passed (only in my solution, I didn't test yours). |
|