Saturday, June 24, 2017

Count all numbers up to A that have sum of digits equal to S

1 <= A < 10^15
1 <= S <= 135
আমরা যদি A পর্যন্ত সকল সংখ্যা generate করি এবং sum এর সমান কিনা তা check করি তাহলেই আমরা আমাদের answer পেয়ে যাব।
000
001
.
.
188
189
.
.
244
245
.
.
257
258

আমাদের কে প্রথমে জানতে হবে ডিজিট সংখ্যা কয়টি। এখানে আমরা ৩ ডিজিট এর সংখ্যা ধরেছি A।

আমরা ৩ ডিজিট এর সকল সংখ্যা generate করতে পারব। কিন্তু A এর উপরের সংখ্যা generate করে আমাদের কোন লাভ হবে না। তাই A পর্যন্ত limit দিয়ে  ৩ ডিজিট এর সংখ্যা generate করব।

আমরা আগেই n ডিজিট এর সকল সংখ্যা কিভাবে generate করা যায় তা দেখেছি এখানে

এখন আমরা দেখবো A পর্যন্ত limit কিভাবে সেট করা যায়।

আমরা একটা recursive function লেখতে পারি। যার প্যারামিটার হবে 3ta  current_digit_no  ,sum_left , limit ।

আমরা এভাবে চিন্তা করতে পারি A = 2(0 তম ডিজিট ) 5 (1 তম ডিজিট) 6 (2 তম ডিজিট) 8 (3  তম ডিজিট)।

function er limit parameter আমাদের বলবে আমরা যে ডিজিট এ আসছি তার limit পর্যন্ত নিতে পারব না সব সংখ্যা নিতে পারব।

০ তম ডিজিট এর জন্য আমরা highest ২ পর্যন্ত generate করতে পারব, আমরা যদি ০ তম ডিজিট এ ২ নিয়ে আগাই তাহলে ১ তম ডিজিট এ ৫ পর্যন্ত genetare করতে পারব, আবার আমরা যদি ০ তম ডিজিট এ ০/১ নিয়ে আগাই তাহলে ১ তম ডিজিট এ ০-৯ পর্যন্ত  সব গুল ডিজিট নিয়ে আগাইতে পারব। পরের ডিজিট এর জন্য same কাজ হবে।

আমরা limit এর ২টা value ঠিক করব।

যখন limit == 0 তখন প্রতিবার ০ - ৯ এর মধে সবগুলো সংখ্যা নিয়ে একবার আগাবো যদি sum_left - সংখ্যা >= ০ হয় সাথে sum_left থেকে সংখ্যা টা বিয়োগ করে দিব আর limit 0 পাথাব।

আর যখন limit == 1 তখন ঐ ডিজিট এর highest_limit বের করব। প্রতিবার ০ ঠেকে  highest_limit এর মধে সবগুলো সংখ্যা নিয়ে একবার আগাবো যদি sum_left - সংখ্যা >= ০ হয় সাথে sum_left থেকে সংখ্যা টা বিয়োগ করে দিব। সংখ্যাটা highest_limit এর চে ছোট হলে limit = 0 পাঠাব আর highest_limit এর সমান হলে limit = 1 পাঠাব।

BaseCase:

যদি current_digit_no যদি n হয়ে যায় আর sum_left ০ হয়ে যায় তার মানে আমরা এমন একটা n ডিজিট বিশিষ্ট সংখ্যা পায়ে গেছি যার ডিজিট গুলোর যোগ ফল sum এর সমান। তাই আমরা ১ return করব।



যদি current_digit_no যদি n হয়ে যায় আর sum_left ০ না হয় তার মানে আমরা যে সংখ্যা generate করেছি যার ডিজিট গুলোর যোগ ফল sum এর সমান না। তাই আমরা ০ return করব।

dynamic programming:

function টার recursive tree আঁকলে দেখবো যে এখানে overlapping subproblem পাওয়া যাবে। তাই যদি আমরা memorization করতে পারি। 

#include<bits/stdc++.h>
using namespace std;
string s;
int n;
int dp[10][95][3]; // digit number max = 10 (0<=A<=10^10)
/// as there can be at most 10 digit the max sum can be 9*10 = 90 so if input sum > 90 then answer will be 0
string int_to_string(int a){
stringstream ss;
ss << a;
string str = ss.str();
return str;
}
long long f(int current_digit_no,int sum_left,int limit){
if(current_digit_no==n){
if(sum_left==0) return 1;
return 0;
}
if(dp[current_digit_no][sum_left][limit]!=-1) return dp[current_digit_no][sum_left][limit];
long long total = 0;
if(limit==0){
for(int i=0;i<10;i++){
if((sum_left-i)>=0) total += f(current_digit_no+1,sum_left-i,0);
}
}
else{
int highest_limit = (int) (s[current_digit_no] - '0');
for(int i=0;i<=highest_limit;i++){
if((sum_left-i)>=0){
if(i==highest_limit) total += f(current_digit_no+1,sum_left-i,1);
else total += f(current_digit_no+1,sum_left-i,0);
}
}
}
return dp[current_digit_no][sum_left][limit] = total;
}
int main(){
int a,sum;
cin>>a>>sum;
s = int_to_string(a);
n = s.size();
memset(dp,-1,sizeof(dp));
long long z = f(0,sum,1);
cout<<z<<"\n";
}

Friday, June 23, 2017

Given n & sum find all the n digit numbers with sum of digit as sum with no leading zero

1 <= n <=20
1<= sum <= 500000

n টা ডিজিট এর প্রতিটায় ০ - ৯ ১ বার বসিয়ে আমরা মোট n^10 টা সংখ্যা generate করতে পারি। কিন্তু আমাদের বলা হয়েছে যে generate করা সংখ্যাটার প্রথম ডিজিট ০ হতে পারবে না। তাহলে আমরা প্রথম ডিজিটটাকে আলাদা ভাবে handle করব।


আমরা একটা recursive function লেখতে পারি। যার প্যারামিটার হবে n এর কত গুল ডিজিট বাকি আর আমার sum কত টুকু বাকি।

আমরা প্রতিবার ০ - ৯ এর মধে সবগুলো সংখ্যা নিয়ে একবার আগাবো যদি sum_left - সংখ্যা >= ০ হয় সাথে sum_left থেকে সংখ্যা টা বিয়োগ করে দিব।

BaseCase:

যদি num_of_digit_left যদি ০ হয়ে যায় আর sum_left ০ হয়ে যায় তার মানে আমরা এমন একটা n ডিজিট বিশিষ্ট সংখ্যা পায়ে গেছি যার ডিজিট গুলোর যোগ ফল sum এর সমান। তাই আমরা ১ return করব।

যদি num_of_digit_left যদি ০ হয়ে যায় আর sum_left ০ না হয় তার মানে আমরা যে সংখ্যা generate করেছি যার ডিজিট গুলোর যোগ ফল sum এর সমান না। তাই আমরা ০ return করব।

প্রথম ডিজিটটাকে আলাদা ভাবে handle:

যেহেতু প্রথম ডিজিট ০ হতে পারবে না তাই আমরা প্রথম ডিজিটটাতে ০ ছাড়া বাকি ৯ টা  সংখ্যার  সবগুলো সংখ্যা নিয়ে একবার  আগাবো।

dynamic programming:
আমরা যদি n = ৫ আর sum যে কোন সংখ্যা দিয়ে function টার recursive tree আঁকলে দেখবো যে এখানে overlapping subproblem পাওয়া যাবে। তাই যদি আমরা memorization করতে পারি। (20*500000 =  < 10^8 যা ম্যাক্সিমাম কোন  array এর সাইজ)
#include<bits/stdc++.h>
using namespace std;
unsigned long long dp[21][500001];
unsigned long long f(int num_of_digit_left,int sum_left){
if(num_of_digit_left==0){
if(sum_left==0) return 1;
return 0;
}
if(dp[num_of_digit_left][sum_left] !=-1) return dp[num_of_digit_left][sum_left];
unsigned long long s = 0;
for(int i=0;i<10;i++) if(sum_left-i>=0) s += f(num_of_digit_left-1,sum_left-i);
return dp[num_of_digit_left][sum_left] = s;
}
unsigned long long ff(int num_of_digit,int sum){ ///for not having leading zero
unsigned long long s = 0;
for(int i=1;i<10;i++) if(sum-i>=0) s += f(num_of_digit-1,sum-i);
return s;
}
int main(){
int n,sum;
memset(dp,-1,sizeof(dp));
cin>>n>>sum;
cout<<ff(n,sum)<<"\n";
}

ToDo List June 2K17

(UVA) Corporative Network (dsu)
(UVA) Fibonacci Sum (don't know)

(UVA)10539 - Almost Prime Numbers (number theory) [DONE]
(UVA) 13153 - Number of Connected Components (number theory + bfs/dfs/dsu) [DONE Finally]

DP:
(UVA) 10943 - How do you add? (Non Classical DP (The Easier Ones) [DONE]
(UVA) Matches (Mediam dp) [DONE]
(UVA) Zeros and Ones (Mediam dp) [DONE]

Bitmask DP:
(LOJ) Marriage Ceremonies (bitmask dp)
(UVA) Free Candies (bitmask dp)

Permutation:
(UVA) 10063 - Knuth's Permutation (permutation)
(UVA) 10098 - Generating Fast (permutation)

DIGIT DP:
(SPOJ) LUCIFER - LUCIFER Number (Digit dp) [DONE]
(SPOJ) RAONE - Ra-One Numbers (Digit dp)
(SPOJ) GONE - G-One Numbers (Digit dp)
(SPOJ) NUMTSN - 369 Numbers (Digit dp)
(SPOJ) LOTGAME - New Lottery Game (Digit dp)
(LOJ) Fast Bit Calculations (Digit dp) [DONE]
(LOJ) Investigation (Digit dp) [DONE]
(LOJ) How Many Zeroes (Digit dp) [DONE]
(LOJ) Palindromic Numbers (Digit dp)


Football Player Transfer Prediction

Football Player Transfer Prediction Using Different Classifiers Project Report :  Football Player Transfer Prediction Report ...