2020.02.01【NOIP普及组】模拟赛C组(纪中)

T1

*本觉得是一道水题,没怎么在意,结果只得了特殊点的分10分 *
题目描述:
PYWBKTDA最近正在打怪兽,一个斯拉夫神话中的凶猛怪兽,一个有着多个头的巨大龙状爬行
动物。
开始的时候,怪兽有X个头,你有n种打击方式。如果你选择第i种打击方式,这个神奇的怪兽会减
少min(d i ,cur)个头。这里cur表示当前怪兽拥有的头的数量。但是如果怪兽被打击以后还至少留下
了一个头,那么它就会再长出h i 个头来。当cur = 0或者小于0的时候,怪兽被打败了。
注意,你可以使用任何一种打击方式任何次数,以任何的顺序。
例如,如果当前cur = 10,d = 7,h = 10,那么一次打击以后怪兽就会有13个头了(因为减少了7个
头以后,怪兽还剩下3个头,再加上10个头)。但是如果当前cur = 10,d = 11,h = 100,那么怪兽就被打
败了。
输入

第一行输入是两个整数n和x,分别表示打击的种类和开始时候怪兽的头的数量。
接下来n行, 每行两个整数描述了d i 和h i ,表示第i种打击减少的头的数量和会长出来的头的数量。

输出

输出只有一个整数,表示最少需要打击的次数,如果怪兽无法被打败,就输出−1。

  • 分析
    大意是,py…这个人在打怪,把怪的头打完,则胜利。他有n种打击,规定你选则第i种方式,能打掉di个头。
    这道题我们必须分情况讨论,能打败和不能打败。
    能打败:
    我们用一个while循环来判断x(怪兽当前有多少个头)是否小于等于0。
    然后再判断怪兽头能否一次击败,能则输出需要次数+1(sum)。
    不能,则让怪兽头去减n种方法中最大的纯打击方式max(di-hi)
    不能打败
    则是一开始就判断n种打击方式是否都是负打击(di<=hi),如果是则sum++。
    然后再判断他是否有一种方式能一次打败怪兽,如果能,输出1,return 0;如果不能并sum=x
    则输出-1.

code:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int d[110],h[110],th[110];
int main()
{
	freopen("monster.in","r",stdin);  //文件输入输出 
	freopen("monster.out","w",stdout);
	int n,sum=0,t;
	cin>>n>>t;
	for(int i=1;i<=n;i++)
	{
		cin>>d[i]>>h[i];
		if(h[i]>=d[i]&&t>d[i]) sum++;   //判断是否都是负打击
		th[i]=d[i]-h[i];
	}
	for(int i=1;i<=n;i++)  //判断是否能一次打败怪兽
	{
		if(d[i]>=t)
		{
			cout<<1<<endl;
		    return 0;
		}
	}
	if(sum==n) 
	{
		cout<<-1<<endl;
		return 0;
	}
	sum=0;
	int maxx=th[1]; 
	for(int i=2;i<=n;i++)   //做判断,找最大的纯打击方式
		if(th[i]>maxx) maxx=th[i];	
	while(t>0)  //能打败流程
	{
		for(int i=1;i<=n;i++) 		
			if(d[i]>=t)
			{
				cout<<1+sum<<endl;
				return 0;
			}
		t-=maxx;
		sum++;
	} 
	cout<<sum<<endl;  //输出sum,华丽结束!
	return 0;
}

---- -----------------------------------华丽的分割线-------------------------------------------------------------------------------

T2

一开始没有看懂题意,以为x越小,位置越上,则被题目坑了50分!
题目描述
PYWBKTDA有一块白板,这块白板的四条边分别平行于坐标轴。我们可以假设这块白板的左
下角在(x 1 ,y 1 )位置,右上角在(x 2 ,y 2 )位置。
现在有两块黑板放到白板的上面,这两块黑板的四条边也是平行于坐标轴的。我们可以设第1块
黑板的左下角是(x 3 ,y 3 ),右上角在(x 4 ,y 4 )位置, 第2块黑板的左下角是(x 5 ,y 5 ),右上角在(x 6 ,y 6 )位置。
在这里插入图片描述
现在你的任务是来判断,我们从上往下看,是否有白板的部分区域可以被看到。所谓的白板部分
区域被看到的意思是,白板上至少有一个点没有被黑板遮住。

输入

输入第一行有一个整数t,表示数据的组数。
接下来每组数据:
输入的第一行包含4个整数,分别表示x 1 ,y 1 ,x 2 ,y 2 ,即白板的左下角和右上角。
输入的第二行包含4个整数,分别表示x 3 ,y 3 ,x 4 ,y 4 ,即第1块黑板的左下角和右上角。
输入的第三行包含4个整数,分别表示x 5 ,y 5 ,x 6 ,y 6 ,即第2块黑板的左下角和右上角。

输出

输出有t行,对于每组数据,如果有部分白板可以被看到,就输出Y ES,否则就输出NO。

题目的坐标系是这样的:
在这里插入图片描述

看完题目后,我们进人正题。
这道题我们还是分情况来做。
一种是没有白板可以被看到
则分为六种情况:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

那有部分白板可以被看到的情况就简单了,一个bool判断即可。

code:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long t,b,x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6;
int main()
{
	//freopen("sheet.in","r",stdin);
	//freopen("sheet.out","w",stdout);
	cin>>t;
	for(int i=1;i<=t;i++)
	 {
	 	b=0;
		cin>>x1>>y1>>x2>>y2;
	 	cin>>x3>>y3>>x4>>y4;
	 	cin>>x5>>y5>>x6>>y6;
	 	//六种情况
	 	if(x3<=x1&&y3<=y1&&x4>=x2&&y4>=y2)b=1;
		if(x5<=x1&&y5<=y1&&x6>=x2&&y6>=y2)b=1;
		if(x3<=x1&&y3<=y1&&x6>=x2&&y6>=y2)
		{
		 if(x4>=x1&&y4>=y2&&x5<=x2&&y5<=y1&&x4>=x5)
		  b=1;
		 if(x4>=x2&&y4>=y1&&x5<=x1&&y5<=y2&&y4>=y5)
		  b=1;
		}
		if(x5<=x1&&y5<=y1&&x4>=x2&&y4>=y2)
		{
		 if(x6>=x1&&y6>=y2&&x3<=x2&&y3<=y1&&x6>=x3)
		  b=1;
		 if(x6>=x2&&y6>=y1&&x3<=x1&&y3<=y2&&y6>=y3)
		  b=1;
		} 
		if(b==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;      
	 }
	return 0;
}

T3

T4

发布了80 篇原创文章 · 获赞 58 · 访问量 2550

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/104144711