ماراح اجاوب .. أنت عارف السبب هههههههه
بس حبيت ادخل .. واقول لك " اشتقت لك " .. وكيف اختباراتك .. !!
ربي يوفقك يابطل
ماراح اجاوب .. أنت عارف السبب هههههههه
بس حبيت ادخل .. واقول لك " اشتقت لك " .. وكيف اختباراتك .. !!
ربي يوفقك يابطل
اقتباسماراح اجاوب .. أنت عارف السبب هههههههه
مالسبب يا ترى !؟
اقتباسبس حبيت ادخل .. واقول لك " اشتقت لك " .. وكيف اختباراتك .. !!ربي يوفقك يابطل
الإمتحان النهائي انتهى أمس و نتائجي في الإختبارات جيدة و لله الحمد :)
لا تنساني من صالح الدعاء.
ملاحظة:مضى علي زمن طويــــــــل ولم أجدك في الماسنجر ! مالسبب ياترى !؟
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
عرض علي الأخ namespace الفكرة التالية:
اقتباسما رأيك بحل آخر ليس فيه أي وجود لجملة شرطية if statement حيث الـ complexity أقل ما يمكن ؟؟؟
فأجبته بــ:
اقتباسفكرة جيدة و لعلك أول من اكتشفها .. ورينا شطارتك :wub: :)
فقام باستنتاج طريقة ثالثة في غاية الروعة :wub: سأعرضها لكم عندما تنتهي الفترة المحددة :)
بانتظار إبداعاتكم
دمتم بود.
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
قام الأخ الغالي و المشرف المميز هويدي بإثراء هذه المسابقة بمحاولة جديدة تؤدي المطلوب بشكل كامل وقد استخدم فيها التراكيب :wink:
للتنبيه:
بقي 4 ساعات تقريبا على انتهاء الفترة المحددة :)
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
تم إرسال حل اللغز
شكرا أخي أحمد على هذا الإطراء الذي لا أستحقه
المشكله أني قادم من بيئة object oriented (الجافا), فستجد حلولي دائما تحاول أن تستخدم خصائصها :D
تم تعديل هذه المشاركة بواسطة هويدي في 26 يونيو 2010 في 19:51
اقتباستم إرسال حل اللغز
تفكير رائع و محاولات أروع :wub:
قام الأخ الغالي aohammed بحل اللغز و ذلك بطريقتين :)
اقتباسشكرا أخي أحمد على هذا الإطراء الذي لا أستحقه
:blush: :blush: :blush:
اقتباسالمشكله أني قادم من بيئة object oriented (الجافا), فستجد حلولي دائما تحاول أن تستخدم خصائصها :D
هذه ليست مشكلة .. بل هي نقطة تعد لصالحك :)
تنبيه:
أرجوا من الإخوة الذين لم يقدموا لي شرح طرقهم المسارعة قبل انتهاء الفترة المحددة .. بقي ساعتان.
الإخوة الذين لم يقدموا شرح فكرهم:
الأستاذ خالد الشايع
الأخ عماني
المشرف المميز هويدي
الأخ aohammed
دمتم بود.
تم تعديل هذه المشاركة بواسطة أحمد المتألق في 26 يونيو 2010 في 23:08
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
:)
تم تعديل هذه المشاركة بواسطة Wajdy Essam في 26 يونيو 2010 في 22:34
http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة
https://moalfat.com للكتب الالكترونية والكورسات التعليمية
Everything we see now is just an engineering solution based on old science
متشوق لرؤية مختلف الحلول
أتمنى أن يكون حلي هو الأقصر والأسرع
ولست متأكداً مع وجود مبدعين في هذا المنتدى
البرمجة = الرياضيات
مرحبا بأستاذي الكريم وجدي عصام :wub:
اقتباسبعد ملاحظة الحل بالطريقة العادية _حلقتين loop_ توضح بعد طباعة index تلك الأبواب ، ان الباب المفتوح هو الذي يكون جذره عدد صحيح، أما المغلقة هي التي تكون جذرها عدد حقيقي..
ما شاء الله تفكير جميل :)
بالمناسبة كانت هذه إحدى طرقي لحل اللغز بقيت لي الآن طريقة واحدة ...! :blush:
اقتباسمتشوق لرؤية مختلف الحلولأتمنى أن يكون حلي هو الأقصر والأسرع
ولست متأكداً مع وجود مبدعين في هذا المنتدى
سترى الحلول قريبا بإذن الله :) و بالنسبة لسؤالك فأقصر حل وصلني إلى حد الآن هو الحل الذي قدمه الأستاذ وجدي عصام يليه حل الأستاذ خالد الشابع ثم حلك أنت :) يعني أنت في المركز الثالث من حيث قصر الحل و في المركز الأول من حيث كثرة الحلول
ألف مبروك :wub:
دمتم بود.
تم تعديل هذه المشاركة بواسطة أحمد المتألق في 26 يونيو 2010 في 22:52
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
لقد أرسلت شرحي في رد على الرسالة الأصلية أخ أحمد :ohmy:
اقتباسمتشوق لرؤية مختلف الحلول
أتمنى أن يكون حلي هو الأقصر والأسرع
ولست متأكداً مع وجود مبدعين في هذا المنتدى
أظنه سيكون أسرع من حلي :)
هذه الجملة خاطئة :wacko:
اقتباسلقد أرسلت شرحي في رد على الرسالة الأصلية أخ أحمد :ohmy:
عفوا لم أنتبه على شرحك ...! :blush:
اقتباسأظنه سيكون أسرع من حلي :)
هو كذلك :wub:
جاري جمع و تنسيق الحلول المقترحة :wink:
تم تعديل هذه المشاركة بواسطة أحمد المتألق في 26 يونيو 2010 في 23:12
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
اقتباسان الباب المفتوح هو الذي يكون جذره عدد صحيح
أهنئك على الفكرة الرائعة . . .
ما رأيك إذا أعطيتك تفسيراً لحل الأخ وجدي عصام ؟ لماذا الذي جذره عدد صحيح دون غيره ؟
هل لأننا مشينا بالأمور بطريقة عكسية وطبعنا محتوى المصفوفة doors ولاحظنا تلك الملاحظة وأعدنا كتابة الكود
أم أن بإمكاننا تفسير الأمر وكتابة الكود بناءً على ذلك التفسير ؟
هل تعلم قدر الفائدة الذي كسبناه من موضوعك ؟
أنا أعلم لكن لن أخبرك :)
البرمجة = الرياضيات
اقتباسأهنئك على الفكرة الرائعة . . .
انت أروع :wub:
اقتباسما رأيك إذا أعطيتك تفسيراً لحل الأخ وجدي عصام ؟ لماذا الذي جذره عدد صحيح دون غيره ؟
أنا أعلم السبب :) كما ان الأستاذ وجدي عصام قدم تبريرا لفكرته :) و لكن لا بأس بأن تفيدنا بفكرة جديدة :wink:
اقتباسهل تعلم قدر الفائدة الذي كسبناه من موضوعك ؟
ذاك هو هدفي المنشود :wink: و إن شاء الله تفيدون و تستفيدون أكثر :)
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
اقتباسممكن تعطيني تفسير الأستاذ عصام إذا ما في غلبةرح اعطي تفسيري إذا كان مختلف
سأرسله لك على الخاص و أجبني على الخاص :wink:
تنبيه:
تم الإنتهاء من تسليم محاولات المتعلقة باللغز.
يتم الآن جمع و تنسيق الحلول المقترحة :)
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
السلام عليكم
في انتظار مختلف الحلول :)
الإختبار الأول من المسابقة
احصائيات الإختبار:
عدد الأعضاء الذين قاموا بحل اللغز:9
عدد الأعضاء الذين فشلوا في حل اللغز:1
عدد المحاولات الصحيحة:16
عدد المحاولات الخاطئة:3
تفاصيل الإختبار:
العضو namespace قدم 4 طرق لحل اللغز و قد حطم الرقم القياسي في عدد الحلول بالنسبة للمشتركين :wub:
العضو هويدي قدم 3 طرق لحل اللغز و قد احتل المرتبة الثانية في الإختبار :wub:
العضو aohammed قدم طريقتان لحل اللغز و قد احتل المركز الثالث :wub:
أما باقي الأعضاء فقد قدم كل واحد منهم طريقة واحد لحل اللغز و هم:
xpero,Khaled.Alshaya,Wajdy Essam,omani,Abboodd
الحلول المقترحة:
حلول الأخ namespace :
الطريقة الأولى:
#include<iostream>
using namespace std;
int main()
{
bool doors[1000];
for(int i=0;i<1000;i++)
doors=false;
for(int j=1;j<=1000;j++)
for(int k=1;k<=1000;k++)
{
if(j*k>1000)
break;
else
doors[j*k-1]=!doors[j*k-1];
}
int count=0;
for(i=0;i<1000;i++)
if(doors)
count++;
cout<<"# of open doors is : "<<count<<endl;
return 0;
}الطريقة الثانية:
#include<iostream>
using namespace std;
int main()
{
bool doors[1000];
for(int i=0;i<1000;i++)
doors=false;
for(int j=1;j<=1000;j++)
for(int k=1;k<=1000 && j*k<=1000;k++)
doors[j*k-1]=!doors[j*k-1];
int count=0;
for(i=0;i<1000;i++)
if(doors)
count++;
cout<<"# of open doors is : "<<count<<endl;
return 0;
}الطريقة الثالثة:
#include<iostream>
using namespace std;
int main()
{
bool doors[1000];
for(int i=0;i<1000;i++)
doors=false;
for(int j=1;j<=1000;j++)
for(int k=1;k<=1000/j;k++)
doors[j*k-1]=!doors[j*k-1];
int count=0;
for(i=0;i<1000;i++)
if(doors)
count++;
cout<<"# of open doors is : "<<count<<endl;
return 0;
}الطريقة الرابعة:
#include<iostream>
using namespace std;
int main()
{
int doors[1000];
for(int i=0 ; i<1000 ; i++)
doors=0;
for(int j=1 ; j<=1000 ; j++)
for(int k=1;k<=1000/j;k++)
doors[j*k-1]++;
for(int k=0,count=0 ; k<1000 ; k++)
count+=doors[k]%2;
cout<<"# of open doors is : "<<count<<endl;
return 0;
}شرح الطريقة الأخيرة:
التفسير كالآتي :
نقوم بإضافة 1 على موقع كل باب في المصفوفة doors تم تحريكه سواء بالفتح أو بالإغلاق
( لاحظ أنها معرفة integer )
ثم نحسب عدد الأبواب التي أجرينا عليها حركات فردية ، وذلك بإضافة باقي قسمة عدد الحركات على 2 ، بذلك كأننا نضيف 1 عندما عدد الحركات على الباب فردي ، ونضيف 0 عندما عدد الحركات على الباب زوجي ؛
عندما عدد الحركات فردي : (فتح و اغلاق) ثم (فتح و إغلاق) ثم . . . ثم (فتح و إغلاق ) ثم (فتح) >> الباب في النهاية مفتوح
عندما عدد الحركات زوجي : (فتح و اغلاق) ثم (فتح و إغلاق) ثم . . . ثم (فتح و إغلاق) >> الباب في النهاية مغلق.
حلول الأخ هويدي:
#include <stdio.h>
#define SIZE 1000
typedef struct{
int status; //closed
}door;
int debug=0;
int
main(void){
door d[SIZE+1] = {0};
int i; //person
for (i=1; i<=SIZE; i++){
debug && printf("%i\t: ", i);
int j; //door
for (j=SIZE; j>=1; j--){
if (j%i == 0){
if (d[j].status)
d[j].status =0;
else
d[j].status =1;
}
debug && printf("%i ", (d[j].status));
}
debug && printf("\n");
}
int count=0;
for (i=1; i<=SIZE; i++){
if (d.status) count++;
}
printf("count=%i\n", count);
return 0;
}الطريقة الثانية:
#include <stdio.h>
#define SIZE 1000
typedef struct{
int status;
}door;
int
main(void){
door _door[SIZE+1] = {0};
int i, p=0, d=0;
for (i=0; i<SIZE * SIZE;i++){
if ( i%SIZE == 0) p++; // init p
d = i - ((p-1)* SIZE) + 1; // init d
if (d%p == 0){
if (_door[d].status)
_door[d].status = 0;
else
_door[d].status = 1;
}
}
// display result
int count=0;
for (i=1; i<=SIZE; i++){
if(_door.status) count++;
}
printf("Count is %i\n", count);
return 0;
}الطريقة الثالثة:
#include <stdio.h>
#define SIZE 1000
int
main(void){
int _door[SIZE+1] = {0};
int i, p=0, d=0;
for (i=0; i<SIZE * SIZE;i++){
if ( i%SIZE == 0) p++; // init p
d = i - ((p-1)* SIZE) + 1; // init d
if (d%p == 0){
_door[d] = (_door[d]? 0:1); // if closed, then open else, close.
}
}
//print.
int count=0;
for (i=1; i<=SIZE; i++){
if (_door) count++;
}
printf("count :%i \n", count);
return 0;
}شرح الطريقة الأخيرة:
int _door[SIZE+1] = {0};أولا نقوم بتعريف array طوله 1001 (وذلك لكي نستخدم العناصر التي تحمل فهرس من 1 إلى 1000 ) و نقوم بعمل init له ب 0
int i, p=0, d=0;
نقوم بتعريف متغيرين
المتغير p يمثل رقم الشخص (و سيأخذ القيم من 1 إلى 1000 كما سنري)
المتغير d يمثل رقم الباب (و كذا سيأخذ القيم من 1 إلى 1000)
وطبعا المتغير i كفهرس لل loop
for (i=0; i<SIZE * SIZE;i++){
if ( i%SIZE == 0) p++; // init p
d = i - ((p-1)* SIZE) + 1; // init d
if (d%p == 0){
_door[d] = (_door[d]? 0:1); // if closed, then open else, close.
}
}لنفرض أن الشكل سيكون كالتالي:
d p 1 2 3 4 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0
فال p كما قلنا هو عدد الأشخاص , d هو عدد الأبواب. و بالبداية جميع الأبواب مغلقة (و من هنا القيم 0)
ال loop السابقه ستوم باللف 1000*1000 مره
و في كل مره نحصل على رقم الشخص و رقم الباب
رقم الشخص يحسب كالتالي:
if ( i%SIZE == 0) p++;
وهذا يعني أن في أول 1000 لفه, سيكون رقم الشخص هو 1, و في ثاني 1000 لفه سيكون رقم الشخص هو 2 و هكذا,
وبهذا نضمن أن يكون عندنا 1000 حاله لكل شخص نستطيع بعد ذلك إختبار دخوله على كل باب في كل حاله.
بعد ذلك نقوم بحساب أرقام الأبواب, و نحن هنا نريد لكل شخص, أن يكون عدد الأبواب لدينا دائما من 1 إلى 1000, و قمت بحساب رقم الباب بالكتالي:
d = i - ((p-1)* SIZE) + 1;
و هذا سيعطي لنا لكل شخص, عدد أبواب من 1 إلى 1000
وبالتالي لدينا 1000 شخص و لكل شخص 1000 باب.
الأن سوف نقوم بمحاولة إدخال الأشخاص على الأبواب:
if (d%p == 0){
_door[d] = (_door[d]? 0:1); // if closed, then open else, close.
}و هذا يعني أن لو أن الشخص رقمه هو مضاعفات لرقم الباب, فقم بفتح الباب إذا كان مغلقا و غلقه إذا كان مفتوحا.
ونقوم بتخزين حالة الباب في array الذي قمنا بتعريفه في بدائة البرنامج :
int _door[SIZE+1] = {0};بعد ذلك نقوم بحساب الأبواب المفتوحه:
int count=0;
for (i=1; i<=SIZE; i++){
count += _door;
}
printf("count :%i n", count);حلول الأخ aohammed :
الطريقة الأولى:
void main()
{
bool door[999];
for(int i=0;i<1000;i++)
{
door=false;
}
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=1000;j++)
{
if(j%i==0 && door[j-1]==false)
door[j-1]=true;
else if(j%i==0 && door[j-1]==true)
door[j-1]=false;
}
}
int c=0;
for(int i=0;i<1000;i++)
{
if(door==true)
c++;
}
cout<<c;
}الطريقة الثانية:
void main()
{
bool door[999];
for(int i=0;i<1000;i++)
{
door=false;
}
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=1000;j++)
{
if(i*j<=1000)
{
if(door[i*j]==0)
door[i*j]=1;
else
door[i*j]=0;
}
}
}
int c=0;
for(int i=0;i<1000;i++)
{
if(door==true)
c++;
}
cout<<c;
}حل الأخ Khaled.Alshaya :
#include <cstddef>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
const size_t number_of_doors = 1000 + 1;
// All doors are initially open, because 1 opens them.
// There is no need to include 1 in the calculations.
vector<bool> doors(number_of_doors, true);
for(size_t person = 2; person < number_of_doors; ++person)
{
for(size_t door = person; door < number_of_doors; door += person)
doors[door] = !doors[door];
}
// Door number zero is not included.
cout << count(doors.begin()+1, doors.end(), true);
}حل الأخ Wajdy Essam
#include <iostream>
#include <vector>
#include <numeric>
#include <cmath>
using namespace std ;
inline int reverse (int ch) ;
inline void corssAllDoors (int index, vector<int>& doors);
inline bool isInteger (double number) ;
const int CLOSE = 0 ;
const int OPEN = 1 ;
const int MAX = 1001 ;
int main(int argc, char* argv[]) {
// method 1
vector<int> doors(MAX,CLOSE) ;
for (int person=1; person<=MAX ; person++)
corssAllDoors(person,doors);
int sum = accumulate(doors.begin(),doors.end(), 0); // sum all element
cout << "Number of open doors: " << sum << endl;
// method 2
// if number is perfect sequre (i.e its sqrt is integer) then increase counter
int count = 0 ;
for (int i=1; i<=MAX ; i++) { /* MAX=1001 */
if ( isInteger( sqrt(i) ) )
count++;
}
cout << "Number of open doors: " << count << endl; /* 31 */
return (0);
}
inline bool isInteger (double number) {
return ( number == floor(number) );
}
inline void corssAllDoors (int index, vector<int>& doors) {
for (int i=index; i<MAX; i+=index) {
doors = reverse(doors) ;
}
}
inline int reverse (int ch) {
return (ch==CLOSE)? OPEN:CLOSE ;
}بعد أن استخدمت الطريقة التقليدية وذلك بالمرور من خلال حلقتين ، قمت بطباعة الأبواب التي نتجت في الأخير..
ولاحظت ان الindex لهذه الأبواب تبدأ ب 1 ثم 4 ثم 9 ثم 16 .. وهذه متسلسلة معروفة ولكن لم أستطيع تذكرتها في الأول..
لكن الصديق google دائما في وقت الضيق :) ، فبمجرد كتابة هذه الأعداد تبين لي أنها هي الأعداد المربعه العدد المربع هو الذي تحصل عليه عند تطبيق:
x^2 (و x هو عدد صحيح).
قم بعمل حلقة من 1 الى مثلا 10 .. وقم بتربيع أي عدد منهم والناتج من كل منهم عدد مربع ، والسلسله الناتجة هي:
0, 1, 4, 9, 16, 25, 36 .... الخ
هذه السلسلة هي التي نتجت كindex للأبواب المفتوحة..
الأن لكي أحصل على عدد الأبواب المفتوحة سأقوم بالعملية العكسية، سأحصل على جذر العدد وأرى هل هو عدد صحيح (مثلا 1 أو 4 ) فاذا كان كذلك فهذا يعني انه باب مفتوح (موجود في السلسله) والا اذا كان عدد حقيقي فهذا يعني انه غير موجود بالسلسلة.
تفسير الأخ namespace لفكرة وجدي عصام:
الأشخاص الذين سيؤثرون على الباب 24 مثلاً هم 1 2 3 4 6 8 12 24
وهم الأشخاص الذين يقبل العدد 24 القسمة عليهم بدون باق - أي أنه من مضاعفاتهم
الشخص 1 عندما يفتح الباب فالشخص 24 سيقوم بإغلاقه حيث 24=24÷1
الشخص 2 عندما يغلق الباب فالشخص 12 سيقوم بفتحه حيث 12=24÷2
. . . . . .
كما لاحظ معي أن عدد الأشخاص زوجي ، أي أنه لدينا عدد معين من ( الفتح والاغلاق ) وبالنهاية الباب مغلق
خذ العدد 16 مثلاً ، الأشخاص الذين سيؤثرون على الباب هم 1 2 4 8 16
مما سبق :
الشخص 1 سيفتح الباب ، والشخص 16 سيغلقه حيث 16=16÷1
الشخص 2 سيغلق الباب والشخص 8 سيفتحه حيث 8=16÷2
أما الشخص 4 فعندما يفتح الباب فنحن بحاجة إلى الشخص 16÷4 ليغلقه
وهو الشخص 4 نفسه وهذا مستحيل ، كل شخص يؤثر مرة واحدة على الباب الواحد
كما لاحظ أن عدد الأشخاص فردي ، وهذا وحده يكفي
وهذا لا يكون إلا للمربع الكامل.
حل الأخ Abboodd :
#include <iostream>
using namespace std;
int FindNumOfDividors(int num);
int main()
{
//We use the number of dividors to find out if the door is open or not.
//If the number is odd, the door is open.
//If the number is even, the door is closed
int numOpen= 0;
for (int i= 1; i <= 1000; i++)
{
int n= FindNumOfDividors(i);
if ((n % 2) == 1) //Odd
numOpen++;
}
cout<< "The number of open doors is: "<< numOpen<< endl;
return 0;
}
int FindNumOfDividors(int num)
{
if (num == 1) return 1; //For 1, there's only a single dividor.
int dividors= 2; //There are surely two dividors: 1 and num.
for (int i= 2; i < num; i++)
{
if ((num % i) == 0)
{
dividors++;
}
}
return dividors;
}حل الأخ omani
# include <iostream.h>
void main()
{
int gate[1001][1],i,j,open=0;
//Close All Gates
for( i=1;i<=1000;i++)
gate[0]=0;
for(i=1;i<=1000;i++)
{
//visiting Gates Starting from Gate i
for(j=i;j<=1000;j=j+i)
{
if (gate[j][0]==1)
gate[j][0]=0;
else
gate[j][0]=1;
}
}
//Show open gates
cout<<"Gates Opened Are \n";
for(i=1;i<=1000;i++)
{
if (gate[0]==1 )
{
open++;
cout<<i<<" ";
}
}
cout<<"\n The Total Gates Opened Are:"<<open;
}حل الأخ xpero :
#include <iostream>
using namespace std;
int main()
{
int total=0;
int doors [1001]= {0};
int status [1001]={0};
int step=1;
for(int i=1;i<1001;i++)
{
doors=i;
}
while(step<=1000)
{
for(int i=step; i<=1000; i+=step)
{
if((i%doors)==0)
status++;
}
step++;
}
for(int i=1;i<=1000;i++)
{
if(status%2!=0)
total++;
}
cout <<"Total Open doors : "<<total<<endl;
return 0;
}الفكرة التي اعتمدت عليها هي حساب عدد مرات دخول الاشخاص من الابواب. بما ان الابواب كانت مغلقة في الحالة البدئية فان دخول الشخص رقم 1 سيؤدي الى فتح جميع الابواب.. بينما سيأتي الشخص رقم 2 و سيقوم باغلاق الابواب 2,4,6,...1000 ثم سيأتي الشخص رقم 3 ليغلق الابواب التي لها رقم فردي مضاعف للعدد3 و يفتح الابواب التي لها رقم زوجي مضاعف للعدد 3.
بما انه عند الانطلاق كانت الابواب مغلقة فان:
الدخول الاول سيؤدي ال فتح الباب X
الدخول الثاني سيؤدي الى غلق الباب X
وستكرر العملية بشكل دوري فتح-->غلق-->فتح....
بحساب عدد عمليات الدخول يمكننا استنتاج هل الباب مغلق ام مفتوح بحيث:
اذا كان عدد الدخلات من الباب X فردي فان الباب سيكون مفتوح
و اذا كان عدد الدخلات زوجي سيكون الباب مغلق.
****
نرجع للكود:
#include <iostream>
using namespace std;
int main()
{
int total=0;//المتغير الذي سنضعه فيه عدد الأبواب المفتوحة
int doors [1001]= {0};//مصفوفة تحتوي على أرقام الأبواب من 1 إلى 1000
int status [1001]={0};//مصفوفة تحتوي على حالة الأبواب من 1 إلى 1000
int step=1; //المقدار الذي سنستعمله في الحلقة التكرارية للحصول على أرقام الأشخاص
for(int i=1;i<1001;i++)//نضع أرقام الأبواب من 1 إلى 1000
{
doors=i;
}
while(step<=1000)
{
for(int i=step; i<=1000; i+=step)
{
if((doors%i)==0) //إذا كان رقم الباب من مضاعفات رقم الشخص
status++; //زيادة عدد الدخلات من هذا الباب
}
step++;//زيادة المقدار ب 1 للمرور للشخص الموالي
}
for(int i=1;i<=1000;i++)
{
if(status%2!=0) //اذا كان عدد الدخلات فردي
total++;//نزيد عدد الأبواب المفتوحة
}
cout <<"Total Open doors : "<<total<<endl;
return 0;
}حلولي:
الطريقة الأولى:
#include<iostream>
using namespace std;
int main ()
{
bool portes[1000]={false};//الأبواب مغلقة في البداية
for(int i=1;i<=1000;i++)//هذه الدوراة تمثل الأشخاص
{
for(int j=1;j<=1000;j++)//هذه الدوراة تمثل الأبواب
{
if(j%i==0)//إذا كان رقم الباب مضاعف لرقم الشخص
{
if(portes[j])//إذا كان الباب مفتوحا
portes[j]=false;//سيتم إغلاقه
else//إذا كان الباب مغلقا
portes[j]=true;//سيتم فتحه
}
}
}
int nb_de_portes_ouvertes=0;//هذا المتغير يمثل عدد الأبواب المفتوحة
for(int i=0;i<1000;i++)//الهدف من هذه الدوراة هو المرور على جميع الأبواب
if(portes)//إذا كان الباب مفتوحا
nb_de_portes_ouvertes++;//قم بزيادة عدد الأبواب المفتوحة بواحد
cout<<nb_de_portes_ouvertes<<endl;//أظهر الأبواب المفتوحة
system("pause");
return 0;
}الطريقة الثانية:
#include<iostream>
#include<cmath>
using namespace std;
int main ()
{
int port=0;
for(int i=1;i<=1000;i++)
if(int(sqrt(i))==float(sqrt(i)))
port++;
cout<<port;
system("pause");
return 0;
}الشرح:
يمكننا ملاحظة أن عدد الأبواب المفتوحة يساوي عدد الأعداد التي تقبل جذرا طبيعيا (لا يحتوي على الفاصلة)
لذلك يمكننا استخدام هذه الخاصية من أجل التحقق من حالة الباب (مفتوح او مغلق) فإذا كان رقم الباب يقبل جذرا طبيعيا فهذا يعني انه مفتوح و إلا فهو مغلق :wink:
متى يكون العدد طبيعي !؟ يعني بدون فاصلة ...! الجواب بسيط للغاية وهو:
إذا كان الفرق بين العدد كـ int و العدد كـ float يساوي صفر فهذا يعني أنه لا يحتوي على فاصلة :)
سأعطيك مثال:
لنأخذ العدد 3 , يمكننا كتابته 3.000000 لاحظ أن الفرق بين العددين يساوي صفر .. إذن العدد 3 لا يحتوي على الفاصلة , لنأخذ عدد آخر و ليكن 8.346598 عندما نقوم بتحويل العدد السابق إلى int فسيكون 8 لاحظ أن الفرق بين العددين في هذه الحالة يساوي 0.346598 إذن فهما غير متساويان مما يعني أن العدد يحتوي على فاصلة.
وهكذا يمكننا التحقق من الأعداد التي تقبل جذرا طبيعيا و الأخرى التي تقبل جذرا حقيقيا.
أرجوا ان تكون الفكرة واضحة و أي استشكال في إحدى طرقي فأنا جاهز :)
ملاحظة:أقصر حل للغز المطروح هو حلي و بالتحديد الطريقة الثانية :wub:
الآن نترك المجال لاستفسارات الأعضاء حول الحلول المقترحة و سيتم توضيح هذه الإستشكالات من طرف صاحب الحل فقط.
يُسمح بطرح الإستفسارات و الرد عليها خلال يوم واحد و بعدها سيقوم العضو namespace بطرح لغز جديد و ذلك لأنه الفائز في الإختبار الأول و ذلك لحصوله على أكبر عدد من ممكن من حلول اللغز.
تنبيه:
أرجوا من الإخوة الذين لم يشرحوا طرقهم أو الذين لم يشرحوا كل طرقهم المسارعة قبل انتهاء الزمن المخصص لشرح الطرق.
تم تعديل هذه المشاركة بواسطة أحمد المتألق في 27 يونيو 2010 في 13:20
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
السلام عليكم و رحمة الله و بركاته,
أخ وجدي, من أين أتيت بهذا الحل العجيب :cool:
أود أن أفهم جوابك أكثر بعد إذنك,
بداية, وضعت حلي بناءً على المعلومة التالية: أي باب, سيمر عليه أشخاص بعدد قواسمه الصحيحة. فمثلاً, العدد 4 سيمر عليه 1, 2, 4 و كما تلاحظ, فإن الباب في الأساس يكون مغلقاً, و فتح بالواحد و أغلق بـ 2 و فتح مرة أخرى بـ 4. إذاً, إذا كان عدد الأشخاص الذي يمرون على باب ما فردياً, فإنه سيكون مفتوحاً, و إذا عددهم زوجياً, سيكون مغلقاً. الأبواب ذات الأعداد الأولية كلها ستكون مغلقة, لأن عدد القواسم زوجي, العدد 1 و العدد الأولي نفسه.
تمام؟
كل ما علينا هو الحصول على قواسم العدد, و بناء على كونها زوجية أو فردية, يمكننا أن نحدد كون الباب مفتوحاً أم لا.الذي أعرفه, أن عدد القواسم لاتوجد له دالة تعوض فيها مباشرة Explicit. و حتى الدوال التي تقبل التعويض المباشر, تشترط حصولك على الأعداد الأولية المكونة و تكراراها المكون للعدد.
كل ما يقوم به حلي, هو أن يمر على قواسم أي عدد بطريقة الـ Sieving. السؤال هو كيف يمكنك القول بأن الـ perfect squares هي الوحيدة فقط التي لديها عدد قواسم فردي؟ ربما هناك شيء لم أفهمه في حلك, و أعتقد أني أغفلت أشياء بسيطة أخرى.
تحياتي أخ وجدي,,,
ياااااااااااااااااااه الحل صحيح :lol:
ما فهمته أن الـ perfect squares بالفعل هي الأعداد الوحيدة التي تمتلك عدد فردياً من القواسم!
السبب بسيط, و لا أدري لماذا لم أقرأ ذلك في الصفحة التي وضعتها في مشاركتي السابقة :)
http://en.wikipedia.org/wiki/Divisor_function#Properties
اقرأ أول سطر.
على العموم, هنا الإثبات:
بما أن أي قاسم لعدد ما ينتج عن قسمة العدد الأصلي به, عدد صحيح آخر, إذا القواسم توجد على شكل أزواج. إلا في حالة perfect squares سيكون هناك زوج عبارة عن العدد نفسه: أي n*n.
بصراحة لم أتصور أن يكون الحل بهذه البساطة :)
بالنسبة لحلك الثاني :
#include<iostream>
#include<cmath>
using namespace std;
int main ()
{
int port=0;
for(int i=1;i<=1000;i++)
if(int(sqrt(i))==float(sqrt(i)))
port++;
cout<<port;
system("pause");
return 0;
}يمكننا الاستغناء عن cmath واقترانه sqrt واختصار عدد مرات الدوران وتلافي جملة الشرط كما يلي :
#include<iostream>
using namespace std;
int main ()
{
int port=0;
for(int i=1 ; i<=1000 && i*i<1000 ; i++)
port++;
cout<<port<<endl;
return 0;
}وإذا أردت استخدامها يمكنك كتابة الكود التالي ، أيضا عدد الدورانات أقل ولا جملة شرط :
#include<iostream>
#include<cmath>
using namespace std;
int main ()
{
int port=0;
for(int i=1 ; i<=sqrt(1000) ; i++)
port++;
cout<<port<<endl;
return 0;
}بالنسبة للتفسير كنت بعثته إليك على الخاص قبل أن تكتب الحلول
اقتباسكما لاحظ أن عدد الأشخاص فردي ، وهذا وحده يكفيوهذا لا يكون إلا للمربع الكامل
أشكر جهودك . . .
البرمجة = الرياضيات
السلام عليكم ...
عموماً يمكن حل السؤال بـ Formula:
السبب بسيط, و هو أن كل عدد prefect square نريد أن نضمنه في العد, لابد أن يكون جذره أقل من 1000 مثلاً. إذاً عدد الـ perfect squares هو نفس عدد الأعداد الأقل من جذر 1000 لأن كل عدد أقل أو يساوي جذر 1000 عند ضربه بنفسه يعطي perfect square أقل من 1000. بالنسبة لدالة الـ Floor فهي لكي نقول بأن العدد الذي نريد أن نضمنه في العد, لابد أن يكون حاصل ضربه بنفسه أقل أو يساوي من عدد الأبواب.
تحياتي :)
تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 27 يونيو 2010 في 06:09
Khaled.Alshaya كتب:عموماً يمكن حل السؤال بـ Formula:
أفهم من كلامك :
cout << (int)sqrt(1000) << endl;
طلعت متخبية بقشة :lol:
البرمجة = الرياضيات
وبكده يكون الحل في سطر واحد ,,
ههههههههه
على كل, بجد ربنا يبارك فيك يا أخ أحمد يا متألق, بجد أنا سعيييييييييييييييييييييد جدا بنظام الأسئلة دي, ربنا يجازيك عنا كل خير..
هذا الموضوع مغلق.