অনেক সময়ই এমন প্রবলেম থাকে যেখানে বলা হয় তুমি একটা ২-ডি অ্যারের কোনো এক পজিশনে আছো, সেখান থেকে তুমি উপরে-নিচে-বামে-ডানে যেতে পারবে। অথবা দাবার বোর্ডে একটা ঘোড়া আছে, তাকে ৮টা দিকে মুভ করানো যায়, এখন কোনো একটা পজিশনে শর্টেস্ট পাথে যেতে হবে। বিগিনার কোডাররা এ ধরণের প্রবলেমে ছোট্ট একটা ট্রিকস না জানার কারণে কোডের সাইজ বিশাল বানিয়ে ফেলে।
ডিরেকশন অ্যারের ট্রিকসটা যারা যানেনা এ ধরণের প্রবলেমে তাদের কোড হয় অনেকটা এরকম:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int x=5,y=3,row=5,col=5,nx,ny; nx=x+1; ny=y; if(nx>=1 && nx<=row && ny>=1 && ny<=col) { DO SOMETHING } nx=x-1; ny=y; if(nx>=1 && nx<=row && ny>=1 && ny<=col) { DO SOMETHING } nx=x; ny=y+1; ............ ............ ............ |
এভাবে বারবার একই লাইন লিখতে লিখতে কোডের চেহারা ভয়াবহ হয়ে যায়, আর কাওকে কোড দেখতে দিলে তারও পাগল হবার অবস্থা হয়! ৮ ডিরেকশনে মুভ করা গেলেতো কথাই নেই। সবথেকে বড় সমস্যা হলো এক জায়গায় চেঞ্জ করলে সবজায়গায় চেঞ্জ করতে হয়।
একটা improvement হতে পারে if(nx>=1 && nx<=row && ny>=1 && ny<=col) এই লাইনের কন্ডিশনটা একটা ম্যাক্রো বানিয়ে ফেলা। যেমন:
1 |
#define valid(nx,ny) nx>=1 && nx<=row && ny>=1 && ny<=col |
এখন if(valid) লিখলেই হচ্ছে। এরপরে DO SOMETHING অংশের কাজগুলোও একটা ফাংশন বানিয়ে ফেললে ঝামেলা কিছুটা কমে, এখন খালি ম্যাক্রো বা ফাংশনে চেঞ্জ করলে সব জায়গায় চেঞ্জ হয়ে যাবে। তারপরেও বার বার কন্ডিশন চেক বা ফাংশন কল করতে হচ্ছে আমাদের। এজন্য আমরা ব্যবহার করবো ডিরেকশন অ্যারে। ৪ দিকে মুভ করা যায় এটার অর্থ হলো:
১. current row এর সাথে ১ যোগ এবং current col এর সাথে ০ যোগ
২. current row এর সাথে -১ যোগ এবং current col এর সাথে ০ যোগ
৩. current row এর সাথে ০ যোগ এবং current col এর সাথে ১ যোগ
৪. current row এর সাথে ০ যোগ এবং current col এর সাথে -১ যোগ
তারমানে x,y পজিশন থেকে উপরে যেতে হলে (x,y)+(1,0) করতে হবে, নিচে যেতে (x,y)+(-1,0) করতে হবে, একই ভাবে ডানে-বামে যেতে যোগ করতে হবে শুধু y এর সাথে।
আমরা দুটি অ্যারে ডিক্লেয়ার করি এভাবে:
1 2 |
int fx[]={+1,-1,+0,+0}; int fy[]={+0,+0,+1,-1}; |
fx[] দিয়ে বুঝাচ্ছি row এর সাথে কত যোগ করবো এবং fy দিয়ে বুঝাচ্ছি y এর সাথে কত যোগ করবো। এবার কাজ খুব সহজ হয়ে গেলো:
1 2 3 4 5 6 7 8 9 10 11 |
#define valid(nx,ny) nx>=1 && nx<=row && ny>=1 && ny<=col int x=5,y=3,row=5,col=5,nx,ny; for(int k=0;k<4;k++) { int nx=x+fx[k]; //Add fx[k] with current row int ny=y+fy[k]; //Add fy[k] with current col if(valid(nx,ny) { DO SOMETHING; } } |
তুমি ৮ দিকে যেতে চাইলে অ্যারেটা হবে এরকম:
1 2 |
int fx[]={+0,+0,+1,-1,-1,+1,-1,+1}; int fy[]={-1,+1,+0,+0,+1,+1,-1,-1}; |
একটু চিন্তা করলেই তুমি দাবার ঘোড়ার মুভের জন্যেও ডিরেকশন অ্যারে লিখতে পারবে। ৩-ডি তেও এটা কাজ করবে, তখন fx[] নামের আরেকটা অ্যারে লাগবে।
তুমি যদি সম্পূর্ণ কোড চাও তাহলে এই বিএফএস এর কোডটা দেখতে পারো:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
//Problem link:http://acm.timus.ru/problem.aspx?space=1&num=1145 #define rep(i,n) for(int i=0; i<(int)n; i++) #define pb(x) push_back(x) #define mem(x,y) memset(x,y,sizeof(x)); #define pii pair<int,int> #define pmp make_pair #define uu first #define vv second using namespace std; #define READ(f) freopen(f, "r", stdin) #define WRITE(f) freopen(f, "w", stdout) int fx[]={1,-1,0,0}; int fy[]={0,0,1,-1}; int mr,mc,mx=0; char w[1000][1000]; int d[1000][1000]; int r,c; void bfs(int x,int y,int dep) { mem(d,63); d[x][y]=0; queue<pii>q; q.push(pii(x,y)); while(!q.empty()) { pii top=q.front(); q.pop(); if(d[top.uu][top.vv]>mx) { mx=d[top.uu][top.vv]; mr=top.uu; mc=top.vv; } rep(k,4) { int tx=top.uu+fx[k]; int ty=top.vv+fy[k]; if(tx>=0 and tx<r and ty>=0 and ty<c and w[tx][ty]=='.' and d[top.uu][top.vv]+1<d[tx][ty]) { d[tx][ty]=d[top.uu][top.vv]+1; q.push(pii(tx,ty)); } } } } int main(){ // READ("in"); int sx,sy,cc=0; cin>>r>>c; swap(r,c); rep(i,r) cin>>w[i]; rep(i,r) rep(j,c) if(w[i][j]=='.'){sx=i;sy=j;cc++;} bfs(sx,sy,0); mx=0; bfs(mr,mc,0); if(cc==1) mx=0; cout<<mx<<endl; return 0; } |
এই কোডটা শুধু ডিরেকশন অ্যারের ব্যবহার দেখানোর জন্য, প্রবলেমটার সলিউশন বের করার কাজ তোমার, ট্রি এর ডায়ামিটার বের করতে বলা হয়েছে প্রবলেমটায়।
হ্যাপি কোডিং!
ফেসবুকে মন্তব্য
Powered by Facebook Comments
জাস্ট লাইক এ বস!
শাফায়েত ভাই,সেগমেন্ট ট্রী এর ল্যাজি প্রপাগেশন নিয়ে একটি আর্টিকেল লিখলে খুব ভালো হত
এটা নিয়ে অনেকেই বলেছে, আমার মাথায় আছে, যেকোনো সময় হয়তো লিখে ফেলবো। ধন্যবাদ।
ভাইয়া, Hashing নিয়ে একটা Post দিলে ভালো হতো। Uva তে অনেক প্রবলেম আছে যেঁগুলোর tag হোল Hashing… কিন্তু এটা কি জিনিস আমি জানি না। Please, সময় করে একটা Post দিবেন।
টপকোডারে Rabin karp এর উপর সুন্দর একটা টিউটোরিয়াল আছে, সেটা পড়লে সহজেই হ্যাশিং বুঝতে পারবে, লিংক।
ভাই , আমি আপনার দেয়া লিংক -এ গিয়েছিলাম কিন্তু ওখানে hashing নিয়ে লেখা এরকম কোনো tutorial খুজেঁ পাই নি ।
Rabin-Karp Algorithm অংশটা দেখো। এই অ্যালগোরিদমটা হ্যাশিং দিয়ে কাজ করে, এটা হ্যাশিং এর উপর টিউটোরিয়াল না হলেও কিভাবে হ্যাশিং করা হয় জানতে পারবে।
শাফায়েত ভাই Crayon Syntax Highlighter টা Problem করছে। কোড Select করতে পারছি না।
কপি করা কি দরকার, নিজে লিখে ফেলো :)। সমস্যাটা কোথায় আমি ধরতে পারলে ঠিক করে দিবো।
ভাইয়া প্রোগ্রামিং এর বেসিক algorithm নিয়ে যদি একটা পোস্ট দিতেন তাহলে খুব সুবিধা হত।
ভাই সময় করে Hashing নিয়ে একটা লেখা লিখে ফেলেন ।
ভাইয়া হ্যাশিং নিয়ে একটা টিউটোরিয়াল লিখলে ভাল হয় .