7.28 杭电杯多校联赛第四场

1004 Link with Equilateral Triangle

题意

n个点,组成一个大三角形,中间内嵌n^2个小三角形,左边不可以编号0,右边不可以编号1,下面不可以编号2,并且每个小三角形的编号之和不能是3的倍数,问给定n,能不能把n个顶点都编好号。

 

思路

猜,找规律,画几个发现根本不可以

代码

cout<<"No"<<endl;

1006 BIT Subway

题意

购买n件物品,有两种计价方式

1. 商品不可拆分付款,一旦满了100元,后面的商品每件八折,一旦再满了200元,后面的商品每件五折。

2.商品可拆分付款,可以把一件商品拆开金额,一部分用去凑满100元,另一部分打8折, 到了200的时候同理,可以将商品拆开,一部分用去填满200元,一部分打5折。

问给定n件商品的价格 两种计价方式各总价多少钱?

思路

第一种计价方式直接设置一个flag,标记当前有没有满100,200,并根据flag用不同折扣。

第二种直接先算总价,然后拆分成3段,第一段内不打折,第二段内8折,第三段内5折。

代码

#include<iostream>
#include<cstdio>
using namespace std;

int n, t;
double a[100005];

int main()
{
	scanf("%d", &n);
	while(n--)
	{
		scanf("%d", &t);
		
		double sum1 = 0, sum2 = 0;
		int flag2 = 0;
		
		for(int i=0; i<t; i++){
			scanf("%lf", &a[i]);
		
			sum1 += a[i];
			
			// 第二种情况
			if(flag2 == 0) sum2 += a[i];
			if(flag2 == 1) sum2 += 0.8*a[i];
			if(flag2 == 2) sum2 += 0.5*a[i];
			
			if(sum2>=100 && sum2<200) flag2 = 1;
			if(sum2>=200) flag2 = 2;
		}
		
		if(sum1>=100){ //第一种情况直接先全部累加然后特判一下
			double cha = sum1 - 100;
			if(cha>=125) sum1 = 200 + (cha - 125)*0.5;
			else sum1 = 100 + cha*0.8;
		}
		
		printf("%.3lf %.3lf\n",sum1,sum2);
	}
}

1007 Climb Stairs

题意

从1到n层有n个人物,有不同的伤害值ai,我在第0层,初始伤害值a0,并且我有一个最大可上升层数k,我只能上升k层以内,或者下降一层,但是我不能走到已经走过的层。 当我的伤害值>=某层人物的伤害值时,我可以将它打败并且吸收它的能力值,问最终能不能打败所有人物。

思路

枚举怪物,如果当前我的伤害值大于它的,那么直接把他吃掉,否则就肯定需要跳跃先吃后面的,那么由于我只能下降一层,所以我们在往后跳的过程中,一旦发现吃掉后面某一段后 (在跳跃范围内) 再回来可以吃掉它的话,那就让我跳到这一段的右边界,然后从那里回来,判断能不能成功回来,如果能成功吃回来,当前点遍历点就跳到右边界的下一个点,否则,在遍历点能直接跳到的范围-1 内继续往后跳,然后检查能不能顺利回去遍历点。

假设当前在第二层:不能吃掉2,那就往后检测,【注意检测边界是我的最大步数的前一步,因为我最后吃完了2还要往前跳,又不能跳到已经吃过的点,所以一定要给自己留一条路】 如果发现必须吃掉3 4之后才够吃2, 那就从4开始往回走,依次判断:当前能否吃掉4,如果能吃掉4能不能吃掉3,....依次判断到2; 如果有一个不能的话,就继续往后检测,检测点跳到5 然后检查5->4->3->2是否顺利,如果都不行,就无解。 如果说从后面某个检测点能顺利回来把2吃完后,那么当前点就跳到检测点的下一个点,继续操作。

 

代码

#include<bits/stdc++.h>
using namespace std;

int n, a0, k, t;
long long a[100010];
long long f[100010]; //前缀和

int main()
{
	cin>>t;
	while(t--){
		cin>>n>>a[0]>>k;
		
		f[0] = a[0];
		for(int i = 1; i <= n; i++) {
			cin>>a[i];
			f[i] = f[i-1] + a[i];
		}
		
		long long sum = a[0], tempsum;
		int j, F, kk;
		
		F = 1;
		for(int i = 1; i <= n; i++)
		{
			if(sum>=a[i]){ // 如果能吃掉 直接吃
				sum += a[i];
				continue;
			}
			
			if(i==n) { //如果现在已经走到了第n个 又吃不掉 那就不行
				F = 0;
				break;
			}
			                     
			int endd = i + k - 1;    //否则先跳到后面再往前吃
			if(endd>=n)  endd = n; //如果可以跳到最后一步
			
			int flag = 0; //记录能不能从后面往前成功吃掉i
			for(j = i+1; j <= endd; j++) {  //遍历能跳到的点
				if(f[j] - f[i] + sum >= a[i]){ //如果一旦发现吃完i+1 到j这一段就能吃掉a[i] 那就从j回溯
					tempsum = sum;
					for(kk = j; kk>=i; kk--){
						if(tempsum >= a[kk]) tempsum += a[kk];
						else  break; //如果发现回到一半回不了了
					}
						
					if(kk == i-1) { //如果顺利回去了i
						flag = 1;
						sum = tempsum;
						//cout<<"从"<<j<<"回溯成功到"<<i<<endl;
						//cout<<"当前伤害值"<<sum<<endl;
						i = j;
						break; //表示当前j可以 不用继续往后找j了
					}
				}
			}
			
			if(!flag) {
				F = 0;
				break;
			}
		}
		
		if(F) puts("YES");
		else puts("NO");
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GTTwelve

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值