(算法练习)——问题 1108: 守望者的逃离

题目:
https://www.dotcpp.com/oj/problem1108.html
这一题自己想的思路很复杂,但提交显示83% 答案错误= =
其实这一题仔细考虑的话,当M剩0/1的话,T>=7用闪烁才有意义,同理,1/2的话,也有个T的范围。。。
笔算了下,对应M为0时,用闪花的时间:
3s 1s 2s 1s 3s 1s 2s 1s ……
60m 60m 60m 60m……
M为4时,用闪花的时间:
2s 1s 2s 1s 3s 1s 2s 1s 3s 1s 2s 1s……
60 60 60 60 60 60……
如果分类讨论,真的又多又杂,而且容易出错(考虑不周全)
看了一个大神的题解豁然开朗:可以一边用闪,一边考虑这一次不用闪,两种方式的路径哪个最长?两个方案平行进行,哪一个最优,max就完事!
打个不恰当的比方,两种计算方式是两个平行宇宙,两边互不知晓对方在平行计算着,一个用闪,闪不够了就憋,另一个机械地+17,当max之后,就确定了它在此时此刻只能有一个走向,但随着时间推进,如果用闪的优势超过了+17,那么max又会成为用闪的结果,当+17更棒,结果就是+17
一个max解决所有问题,不得不说又简洁,又抓住了这题的关键

AC代码如下:

#include <stdio.h>
#define max(a,b) a>b?a:b
using namespace std;

int main(){
	int M,S,T;
	scanf("%d %d %d",&M,&S,&T);
	int linshi = 0,dist = 0;   //中介路径,标准路径 
	for(int t = 1;t <=T;t++){
		if(M>=10){
			M = M-10;
			linshi = linshi + 60;
		}
		else{
			M = M+4;
		}
		dist = max(linshi,dist+17);
		if(dist>= S){
			printf("Yes\n%d\n",t);
			break;
		}
	}
	if(dist< S){
		printf("No\n%d\n",dist);
	}
	
}

贴上我初始复杂还不AC的代码= =

#include <stdio.h>
#include <string.h>

int main(){
	int M,S,T;  //魔法初值,距离S,时间T
	scanf("%d %d %d",&M,&S,&T);
	int linshi = 0;    //路程 
	int i = 1;   //常量 
	int cnt = 0;//记录时间 
	while(M>=10 && T>0){
		M = M-10;
		T--;  //T每次在变 
		cnt++;
		linshi = linshi + i*60;
		if(linshi>=S){
			printf("Yes\n%d\n",cnt);
			break;
		}	
	}    //第一次循环结束,到补充能量时候 

	while( M>= 6 && M <= 9 && T>= 2){    //需要1s 
		T = T - 1;
		cnt++;
		M = M + 4;
		while(M>=10 && T>0){
			M = M-10;
			T--;
			cnt++;
			linshi = linshi + i*60;
			if(linshi>=S){
				printf("Yes\n%d\n",cnt);
				break;
			}	
		}
	}
	while(M>= 2 && M <= 5 && T>= 3){   //需要2s 
		T = T - 2;
		M = M + 8;
		cnt = cnt+2;
		while(M>=10 && T>0){
			M = M-10;
			T--;  
			cnt++;
			linshi = linshi + i*60;
			if(linshi>=S){
				printf("Yes\n%d\n",cnt);
				break;
			}	
		}    
	}
	while(M>= 0 && M <= 1 && T>= 7){   //需要3s //舍弃 
		T = T - 3;
		M = M + 12;
		cnt = cnt+3;
		while(M>=10 && T>0){
			M = M-10;
			T--;  
			cnt++;
			linshi = linshi + i*60;
			if(linshi>=S){
				printf("Yes\n%d\n",cnt);
				break;
			}	
		}    
	}
	while(T>0 && T<4){   //还有时间,只能跑了 
		T--;
		cnt++;
		linshi = linshi + 17*i;
		if(linshi>=S){
			printf("Yes\n%d\n",cnt);
			break;
		}	
	}
	printf("No\n%d\n",linshi);    //没时间了 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值