程序设计与算法学习(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上找了一个视频课用于学习。计划没看一个内容,就跳一下算法自己动手实现一下。作为学习笔记。感觉还挺好的。下面附上视频的链接:程序设计与算法二

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值