枚舉:即一個一個的試,直到找到符合條件的答案爲止。
1.生理週期
人有體力、情商、智商的高峯日子,它們分別每隔 23天、28天和33天出現一次。對於每個人,我們想 知道何時三個高峯落在同一天。給定三個高峯出現 的日子p,e和i(不一定是第一次高峯出現的日子), 再給定另一個指定的日子d,你的任務是輸出日子d 之後,下一次三個高峯落在同一天的日子(用距離d 的天數表示)。例如:給定日子爲10,下次出現三 個高峯同一天的日子是12,則輸出2。
輸入 輸入四個整數:p, e, i和d。 p, e, i分別表示體力、情感和 智力高峯出現的日子。d是給定的日子,可能小於p, e或 i。 所有給定日子是非負的並且小於或等於365,所求的日子小於 或等於21252。
輸出 從給定日子起,下一次三個高峯同一天的日子(距離給定日子 的天數)。
輸入樣例
0 0 0 0
0 0 0 100
5 20 34 325
4 5 6 7
283 102 23 320
203 301 203 40
-1 -1 -1 -1
輸出樣例
Case 1: the next triple peak occurs in 21252 days.
Case 2: the next triple peak occurs in 21152 days.
Case 3: the next triple peak occurs in 19575 days.
Case 4: the next triple peak occurs in 16994 days.
Case 5: the next triple peak occurs in 8910 days.
Case 6: the next triple peak occurs in 10789 days.
代碼:
#include <iostream>
using namespace std;
#define N 21252
int main()
{
int p,e,i,d,counst=0;
while(cin>>p>>e>>i>>d && p!=-1)
{
int k;
for(k=d+1;(k-p)%23;++k);//當(k-p)%23==0(假) 循環結束;找到出現體力高峯時刻
//上個循環 找到了一個體力高峯的時刻,此後每一次+23 都是體力高峯時刻。當下的循環是 找到一個情商高峯
for(;(k-e)%28;k+=23);
for(;(k-i)%33;k+=23*28);
cout<<"Case"<<counst<<": the next triple peak occurs in " << k-d << " days." <<endl;
}
return 0;
}
2.假幣問題
有12枚硬幣。其中有11枚真幣和1枚假幣。假幣和真 幣重量不同,但不知道假幣比真幣輕還是重。現在, 用一架天平稱了這些幣三次,告訴你稱的結果,請你 找出假幣並且確定假幣是輕是重(數據保證一定能找 出來)。
輸入: 第一行是測試數據組數。 每組數據有三行,每行表示一次稱量的結果。銀幣標號 爲A-L。每次稱量的結果用三個以空格隔開的字符串表示: 天平左邊放置的硬幣 天平右邊放置的硬幣 平衡狀態。其 中平衡狀態用``up'', ``down'', 或 ``even''表示, 分 別爲右端高、右端低和平衡。天平左右的硬幣數總是相等 的。 輸出 : 輸出哪一個標號的銀幣是假幣,並說明它比真幣輕還是重。
輸入樣例
1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
輸出樣例
K is the counterfeit coin and it is light.
代碼:
#include <iostream>
#include <cstring>
using namespace std;
char Left[3][7];//存放天平左邊的稱重結果
char Right[3][7];
char result[3][7];//存放三次天平稱重的結果
/*
判斷假幣
假設 c 是假,且輕 所以,測量結果 爲 up 的 右邊 或 down 的左邊 否則不是假幣!
c 是假,且重 up ->左邊 或 down 的右邊 否則不是假幣!
重與輕只是左右結果的差異 且相反
*/
bool isFake(char c,bool light);
int main()
{
int n;//測試數據組數
cin>>n;
while(n--)
{
for(int i = 0;i < 3; ++i) cin >> Left[i] >> Right[i] >> result[i];
for(char c='A';c<='L';c++)
{
if(isFake(c,true))//是假幣 ,且輕
{
cout<<c<<" is the counterfeit coin and it is light."<<endl;
break;
}
else if(isFake(c,false))//是假幣,且重
{
cout<<c<<" is the counterfeit coin and it is heavy."<<endl;
break;
}
}
}
return 0;
}
bool isFake(char c,bool light)
{
for(int i=0;i<3;++i)
{
//指向天平兩邊的字符
char *pLeft,*pRight;
if(light)//輕
{
pLeft=Left[i];
pRight=Right[i];
}
else//重
{
pLeft=Right[i];
pRight=Left[i];
}
/*如果 上面進入的是‘輕’ 則是正常邏輯順序。
如果是‘重’,則pRight存儲的左邊的值,pLeft 存儲的是右邊的值
*/
switch(result[i][0])
{
case 'u':
if(strchr(pRight,c)==NULL)//up-> 在右邊,右邊不存在,即不是假幣
return false;
break;
case 'e':
if(strchr(pLeft,c)||strchr(pRight,c))//平衡時左右兩邊無假幣 即不是假幣
return false;
break;
case 'd':
if(strchr(pLeft,c)==NULL)//down-> 在左邊 左邊存在,即不是假幣
return false;
break;
}
}
return true;//如果假設成立即 爲假幣
}
這個題再寫的時候有一些小問題
如果將Left 改成left 就會出現這個錯誤提示!(對此我也是第一次遇見,尚不知其原因!如有知情者勞煩解釋,感謝)
注:最近想學一下算法,順便練練手。在MOOC上找了一個視頻課用於學習。計劃沒看一個內容,就跳一下算法自己動手實現一下。作爲學習筆記。感覺還挺好的。下面附上視頻的鏈接:程序設計與算法二