সবাইকে সালাম। আমাদের আজকের পর্বটা প্রোগ্রামিং এবং জ্যামিতি নিয়ে তৈরী করা হয়েছে,তবে যে কেউ চাইলে কিংবা আগ্রহ থাকলে এটা পড়তে পারো। LightOJ অনলাইন জাজের কথা মনে হয় অনেকেই শুনে এসেছো। না শুনে থাকলেও সমস্যা হবেনা।

আজকের আলোচ্য সমস্যাটা হচ্ছেঃ

” তোমাকে একটা ধাতব রড দেয়া থাকবে। এটাতে তাপ প্রয়োগ করলে এটা দৈর্ঘ্যে বাড়তে থাকে। এর আদি দৈর্ঘ্য যদি L হয় , তাপমাত্রা সহগ যদি C হয় আর তাপমাত্রা যদি n ডিগ্রী সেলসিয়াস বাড়ানো হয়,তাহলে নতুন দৈর্ঘ্য হবে:

Fig: 06

 সমস্যাটাতে তোমাকে n,C,L এর মানও দেয়া থাকবে। তোমাকে যেই জিনিসটা বের করতে হবে,তা নিচের ছবি দেখলেই বুঝতে পারবেঃ

 

lightOJ 1137

Initial Rod এর দৈর্ঘ্য ছিলো L

After Expansion , রডটার দৈর্ঘ্য হলো L’

রডটাকে আমি একটা দেয়ালের মাঝে যদি রেখে দিই,দেয়ালটার প্রস্থ যদি রডটার আদি দৈর্ঘ্যের সমান হয়,তাহলে এটা আর প্রসারিত না হয়ে বাঁকা হয়ে উপরের দিকে উঠে যাবে। বাঁকা হয়ে উপরের দিকে উঠলে,ছবিতে h এর মান কত হবে সেটাই আমাদের বের করতে হবে।

 

সমাধানঃ

প্রথমেই আমরা একটি সাবপ্রব্লেম সল্ভ করে ফেলবো। Expansion টা সুষম হওয়ায় রডটা এমনভাবেই বাঁকাবে যেন এটা একটা বৃত্তের অংশ হয় এবং একটা Valid বৃত্তচাপ গঠন করে। তাহলে এক কাজ করি, পুরো ব্যাপারটাকে বৃত্তে নিয়ে গিয়ে কল্পনা করে ফেলি। তারপর মূল সমস্যায় ফেরত আসা যাবে।

 

ছবিঃ

Fig

এই ছবিটায় 2c হচ্ছে আমাদের রডটা ( তাপ প্রয়োগ করার আগে) । এই 2c অংশটার ঠিক উপরে যতটুক বৃত্তচাপ আছে,সেটা হচ্ছে তাপ প্রয়োগের পরের অবস্থা। আর b হচ্ছে h ।

a+b = বৃত্তের ব্যাস,এইটুক জানলেই হবে।

 

বৃত্তের আপাতত এতটুক অবস্থা থেকে আমাদের বৃত্তটার ব্যাসার্ধ (r) কোনোভাবে বের করা যায় কিনা,সেটা দেখতে হবে।

kk-1

ত্রিভুজ NOM এবং ত্রিভুজ OXY পরস্পর সদৃশকোণী ত্রিভুজ। ( কেন ? কারণ NOM=XOY=90 Degree , ON=OY তাই OMN=XYO )

তাহলে আমরা বলতে পারিঃ

Eqn1

আচ্ছা, a আর b যদি যোগ করে দিই,আমরা ব্যাস পেয়ে যাচ্ছি,তাই না? তাহলে লিখতে পারিঃ

Eqn2

 

আমরা তাহলে বৃত্তটার ব্যাসার্ধ পেয়ে গেলাম। আমাদের কাজ হচ্ছে এবার এই বৃত্তটার চাপ NXY কেন্দ্রে যে কোণ উৎপন্ন করে,সেটা বের করা। সেটা বের করা আরো সহজ,ছবিটা এঁকে দিলে নিজেরাই বের করে ফেলতে পারবেঃ

Fig: 03

এখানে হাতে আঁকা বিশ্রী থিটার ভ্যালুটা বের করা লাগবে। হালকা পাতলা ত্রিকোণমিতি মেরে দিয়ে এটা বের করে ফেলা যায়।

থিটার মান হবেঃ

Fig: 04

তাহলে , বৃত্তচাপ কেন্দ্রে যে কোণ উৎপন্ন করে,তা হবে এর দ্বিগুণঃ

Fig: 05

এবার , বৃত্তচাপের দৈর্ঘ্য যদি হয় S , তাহলে আমরা লিখতে পারিঃ

Untitled

এ পর্যন্ত যা যা পেলাম তা বসিয়ে দিয়ে পাইঃ

Fig: 07

এখন লক্ষণীয় এইযে, S এর মান আমরা শুরুতেই বের করে ফেলতে পারি। সেটা হচ্ছে,S=L’

তাহলে আমরা আবার S এর মান এত কষ্ট করে বের করছি কেন? আমরা আসলে উপরের সমীকরণটা থেকে S এর মান বের করছি না,বের করার চেষ্টা করছি b এর কোন মানের জন্য আমাদের S এর মান L’ এর সমান হয়!

আমরা আবারো আমাদের S বের করার সমীকরণটিতে চোখ বুলিয়ে আসি। খুব ভালোভাবে এই সমীকরণের Variable এবং Constant ভ্যালুগুলোকে আইডেন্টিফাই করে ফেলো!

খেয়াল করে দেখো,আমাদের উপরের সমীকরণটায়ঃ

c = W/2 , যেটা আমরা শুরুতেই জানি!

b = ভ্যারিয়েবল। এটাই আমাদের আসল উত্তর,মানে উচ্চতা H. এটার একটা একটা করে মান বসিয়ে বসিয়ে চেক করতে থাকবো S কত আসে। এই S যদি L’ এর সাথে মিলে যায়,b ( বা H ) এর সেই মানটাই আমাদের উত্তর!

এখন, একটা একটা করে b এর মান বসানোর কোনো মানে হয়না! মানে যদি থাকতো,তাহলে আমরা সমস্যাটাকে এভাবে সমাধানই করতাম না! আমরা এখানে যেই কাজটা করবো,এই ফাংশনটার একটা প্রপার্টি চেক দিবো। এবং এই প্রপারটিটা হচ্ছে বাইনারী প্রপার্টি!

ফাংশনটাকে একটু পরিবর্তন করে ফেলিঃ

Untitled

এবার, এই ফাংশনটাকে গ্রাফে বসালে ( n,C,L এদের কিছু ট্রায়াল ভ্যালু ব্যবহার করে আমরা ফাংশনটার চেহারা দেখে আসবো )

যা পাইঃ

Graph

গ্রাফটা অনেকখানি Zoom Out করে নেয়া হয়েছে। না হয় তিনটি বিন্দু দেখানো সম্ভব হচ্ছিলো না।

চমৎকার একটা ব্যাপার হচ্ছে, একটা নির্দিষ্ট রেঞ্জ এর মধ্যে গ্রাফটার Increasing প্রপার্টি আছে! x এর যে মানের জন্যে M এর মান 1 হবে,x এর সেই মানটাই আমাদের উত্তর! কেননা , M = 1 হওয়ার অর্থই হচ্ছে S এবং L’ এক হয়ে যাওয়া। ( ফাংশনটার টার্নারী প্রপার্টিও রয়েছে,খুঁজে বের করা তোমাদের দায়িত্ব!)

তো এবার আর কি! x=0 থেকে x=L এই রেঞ্জের মধ্যে বাইনারী সার্চ চালিয়ে দিলেই আমরা পেয়ে যাবো আমাদের কাঙ্ক্ষিত উত্তর! 😀

কোডঃ

আগে নিজে ১ ঘণ্টা চেষ্টা করো। না পারলে কোডটা দেখোঃ

#include <bits/stdc++.h>
using namespace std;

double W,n,C,L,S;

double func(double H)
{
    double r,a;
    double b=H;
    double c=L*0.5;

    r = b/2 + (c*c/(2*b));
    a = 2*asin(c/r);
    return r*a;
}

int main()

{
    int t;
    scanf("%d",&t);
    for(int x=1; x<=t; x++)
    {
        scanf("%lf%lf%lf",&L,&n,&C);

        S=(1.0+(n*C))*L;

        double st=0.0,en=L,mid;

        for(int i=0; i<60; i++)
        {
            mid=(st+en)/2;
            if(func(mid)>S) en=mid;
            else st=mid;
        }
        printf("Case %d: %lf\n",x,mid);
    }

    return 0;
}

সবাইকে ধন্যবাদ। প্রশ্ন থাকলে জানাতে ভুলো না।