程序設計與算法學習(1)——枚舉

枚舉:即一個一個的試,直到找到符合條件的答案爲止。

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''表示, 分 別爲右端高、右端低和平衡。天平左右的硬幣數總是相等 的。  輸出 :  輸出哪一個標號的銀幣是假幣,並說明它比真幣輕還是重。

輸入樣例

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上找了一個視頻課用於學習。計劃沒看一個內容,就跳一下算法自己動手實現一下。作爲學習筆記。感覺還挺好的。下面附上視頻的鏈接:程序設計與算法二

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章