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