Counterfeit Dollar HDU1482题 FZU1003题 POJ1013题

Counterfeit Dollar

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 716    Accepted Submission(s): 282


Problem Description
Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are true silver dollars; one coin is counterfeit even though its color and size make it indistinguishable from the real silver dollars. The counterfeit coin has a different weight from the other coins but Sally does not know if it is heavier or lighter than the real coins. 

Happily, Sally has a friend who loans her a very accurate balance scale. The friend will permit Sally three weighings to find the counterfeit coin. For instance, if Sally weighs two coins against each other and the scales balance then she knows these two coins are true. Now if Sally weighs one of the true coins against a third coin and the scales do not balance then Sally knows the third coin is counterfeit and she can tell whether it is light or heavy depending on whether the balance on which it is placed goes up or down, respectively. 


By choosing her weighings carefully, Sally is able to ensure that she will find the counterfeit coin with exactly three weighings. 

 

Input
The first line of input is an integer n (n > 0) specifying the number of cases to follow. Each case consists of three lines of input, one for each weighing. Sally has identified each of the coins with the letters A-L. Information on a weighing will be given by two strings of letters and then one of the words ``up'', ``down'', or ``even''. The first string of letters will represent the coins on the left balance; the second string, the coins on the right balance. (Sally will always place the same number of coins on the right balance as on the left balance.) The word in the third position will tell whether the right side of the balance goes up, down, or remains even.
 

Output
For each case, the output will identify the counterfeit coin by its letter and tell whether it is heavy or light. The solution will always be uniquely determined.
 

Sample Input
1 ABCD EFGH even ABCI EFJK up ABIJ EFGH even
 

Sample Output
K is the counterfeit coin and it is light.

         这是今天我们新队员的练习题的C题。因为,无人AC所以我在此做下题解。(这个题我自己也是碰到不只一次了,幸好在暑假时看过一个某大神的题解琢磨了整整一天并且AC了,现在还大概记得思路。不得不说当我自己准备开始做这个题时我也后悔了出这个题。)


        首先先说题意:一共有12个硬币,但是,其中必然有一个是不合格的硬币。这个硬币可能比正常的硬币更重,也可能比正常的硬币更轻。现在把所有的硬币依次标记成‘ A ’~‘ K ’,要求你在三次称量后指出不合格的硬币是哪个?而且是更轻还是更重。在这个题中有几个保证:1、在输入的数据中必然有一个不合格的硬币。2、在输入的数据中有且只有一个答案。(题目中的这两个保证很重要。)


然后是思路:

既然题中要我们得出不合格的硬币是哪个那么我就把每个不同的硬币根据称量结果的不同进行标记。

1. 如果一边的硬币比较轻就把它们标记成-1。如果更重就标记成2。(所有的硬币初始化是初始成0。).

2.如果,有某个硬币之前的称量中是偏轻。(也就是-1)然后此次的称量中偏重,则这个硬币必为合格硬币。(具体原因和情况就不做阐述,反正也是如此。)

3.因为题目中已经说明对于每组输入的数据中只有一个不合格硬币,而且有且只有一个正确答案。所以,我们不妨就对于那些“一错再错”的硬币进行“罪加一等”。(对于像第二个条件中的那些“知错就改”的硬币就直接判它“无罪”。)因为,如果那个不合格的硬币是偏轻(偏重),只要它所在的那边也必然是偏轻(偏重)。而对于那些正常的硬币则不是,它们只有当和不合格的硬币在一起时它才会被怀疑是偏轻(偏重),而在不合格的硬币的另一边时则被怀疑成是偏重(偏轻)。


     也许这个解释不太好理解,但是,慢慢消化,慢慢想想就会想通的。因为在题目中已经说明了,对于每一组输入的数据必然有且只有一个唯一的答案。

     

      接下来就是上代码了:(如果你已经写好了代码,建议你先拉到最下面查看那些容易出错的数据。)


#include<stdio.h>
#include<string.h>
int coin[15];              //使用coin数组来记录每个硬币是偏重还是偏轻,同时还包括程度。 
char left[12]; 
char right[12];
/*下面这个就是当天平不平衡时的需要使用的判断函数。其中第一个传入的参数是较轻一方的硬币, 
第二个参数是较重一方的硬币。第三个是两个字符串的长度。(你也可以理解成此方硬币的数量)*/
void judge(char light[],char heavy[],int len){      //当天平不平衡时进行判断的函数。 
	for(int j=0; j<len; j++){
		if(coin[light[j]-'A']==0)     //对于较轻的硬币如果它之前还是0那这次就是它犯罪的开始 
			coin[light[j]-'A']=-1;
		else if(coin[light[j]-'A']>1) //如果这个硬币它之前有过被怀疑是偏重现在又是偏轻。 
				coin[light[j]-'A']=1; //则这个硬币必为合格硬币。(思路第二条。) 
		else if(coin[light[j]-'A']<0) //如果这个硬币之前还是偏轻现在还是偏轻。 
				coin[light[j]-'A']-=1;//那就对它罪加一等。 
		if(coin[heavy[j]-'A']==0)     //对于较重的硬币如果它之前还是0那这次就是它犯罪的开始。 
			coin[heavy[j]-'A']=2;     
		else if(coin[heavy[j]-'A']<0) //如果这个硬币它之前还是被怀疑是偏轻现在有事偏重 
				coin[heavy[j]-'A']=1; //则这个硬币必为合格硬币。 
		else if(coin[heavy[j]-'A']>1) //如果这个硬币之前还是偏重现在还是偏重。 
				coin[heavy[j]-'A']+=1;//那就对它罪加一等。 
	}
}
int main(){
	int n;
	//freopen("数据输入.in","r",stdin); //这是在检测数据进行调试时常用的一个语句。 
	while(scanf("%d",&n)!=EOF) {
		int j;
		while(n--){                       //一共有n组数据每组输入称量三次。 
			memset(coin,0,sizeof(coin));  //对每个硬币的记录进行初始化,初始化为0。 
			for(j=0;j<3;j++){
				char state[5];          //在每次的输入中输入左右两边硬币的状态,up,even或者down 
				scanf("%s",left);       //对天平左边的硬币进行输入。 
				scanf("%s",right);      //对天平右边的硬币进行输入 
				scanf("%s",state);      //输入天平此时的状态。 
				int l=strlen(left);
				if(state[0]=='e') {//因为三个状态的首字母都不同,所以,我们只需通过输入状态的首字母即可 
					for(int k=0; k<l; k++) {   //当首字母是'e'时对应输入的状态就是even。 
						coin[left[k]-'A']=1;   //在此时就直接确定两边的硬币都是合格的标记成'1'。 
						coin[right[k]-'A']=1;
					}
				}
				if(state[0]=='u')       //当状态的首字母是'u'时对应的就是up。也就是左重又轻。 
					judge(right,left,l);//此时向判断judge函数中传入参数。右边的硬币
				                           //作为重的一组传入,左边的则作为轻的一方传入。 
				if(state[0]=='d')       //当状态的首字母是'd'时对应的就是down,也就是左轻又重。 
					judge(left,right,l);//此时向判断judge函数中传入参数.左边的硬币
			                               //作为重的一组传入,右边的则作为轻的一组传入。 
			} 
			int max=0;                        //用max来记下那个“罪刑”最重的硬币。 
			int w;                            //用w来记下“罪刑”最重的硬币的位置。 
			for(j=0;j<12;j++) {               //在判断“罪刑”时涉及两种情况一种是偏轻,另一种是偏重。 
				//printf("%d/",coin[j]);      //在这里加上一个备注输出的是每个硬币中最后的“罪刑”。(有助于调试程序。) 
				if(coin[j]<0&&max<-coin[j]) { //当硬币是偏轻时因为他是以-1为起点,所以,离0越远则“罪刑”越重。 
					max=-coin[j];
					w=j;
				}
				if(coin[j]>1&&max<coin[j]-1) {//当硬币是偏重时因为他是以2为起点,所以,离1越远则“罪刑“越重。 
					max=coin[j]-1;
					w=j;
				}
			}
			printf("%c is the counterfeit coin and it is ",w+'A');//把记录下的位置转化成字符输出。 
			if(coin[w]<0)                      //通过判断不合格硬币中的值来断定此硬币是偏重还是偏轻。 
				printf("light.\n");
			else
				printf("heavy.\n");
		}
	}
	//fclose(stdin);
}


12 

ABCD    EFGH even 
ABCI    EFJK up 
ABIJ    EFGH even 


AGHL   BDEC even 
JKI    ADE up 
J    K even 


ABCDEF   GHIJKL up 
ABC    DEF even 
I    J down 


ABCDEF   GHIJKL up 
ABHLEF    GDIJKC down 
CD     HA even 


A    B up 
B    A down 
A    C even 


A   B up 
B   C even 
DEFG   HIJL even 


ABC    DEJ down 
ACH   IEF down 
AHK    IDJ down 


ABCD   EFGH even 
AB     IJ even 
A    L down 


EFA BGH down 
EFC GHD even 
BA EF down 


A  B up 
A  C up 
L  K even 


ACEGIK   BDFHJL up 
ACEGIL    BDFHJK down 
ACEGLK   BDFHJI down 


ACEGIK    BDFHJL up 
ACEGIL    BDFHJK down 
ACEGLK   BDFHJI up 


对于上面每一组数据对应的输出是:

K is the counterfeit coin and it is light.
I is the counterfeit coin and it is heavy.
I is the counterfeit coin and it is light.
L is the counterfeit coin and it is light.
B is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
L is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
L is the counterfeit coin and it is light.
K is the counterfeit coin and it is heavy.


       这些是我从网上找到的一些容易出错的数据,希望这些对于你调试程序会有帮助。


以上就是我的题解的全部。(下面的可以无视。)

        因为在这个思路明白了后就很简单,但是,做这个题解中最大的难处就是如何让别人明白这个思路。所以,我就把这个题解写的比我当初在暑假中看到的那篇更详细。希望你不用琢磨一天。^_^为了到达这个目的,所以我就是把每次比较过程中偏了再偏的那种情况描述成“罪刑”。我只是希望这样会更好理解,这个解题的思路。如果你因为这个名词把你弄得更混乱了,好吧.........抱歉。。。。。。。





【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于IEEE33节点的配电网韧性提升方法,重点研究了移动储能系统的预布局与动态调度策略。通过Matlab代码实现,提出了一种结合预配置和动态调度的两阶段优化模型,旨在应对电网故障或极端事件时快速恢复供电能力。文中采用了多种智能优化算法(如PSO、MPSO、TACPSO、SOA、GA等)进行对比分析,验证所提策略的有效性和优越性。研究不仅关注移动储能单元的初始部署位置,还深入探讨其在故障发生后的动态路径规划与电力支援过程,从而全面提升配电网的韧性水平。; 适合人群:具备电力系统基础知识和Matlab编程能力的研究生、科研人员及从事智能电网、能源系统优化等相关领域的工程技术人员。; 使用场景及目标:①用于科研复现,特别是IEEE顶刊或SCI一区论文中关于配电网韧性、应急电源调度的研究;②支撑电力系统在灾害或故障条件下的恢复力优化设计,提升实际电网应对突发事件的能力;③为移动储能系统在智能配电网中的应用提供理论依据和技术支持。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析,重点关注目标函数建模、约束条件设置以及智能算法的实现细节。同时推荐参考文中提及的MPS预配置与动态调度上下两部分,系统掌握完整的技术路线,并可通过替换不同算法或测试系统进一步拓展研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值