纪中集训 Day1&Day2

纪中集训 Day1&Day2

Day1

普c都好难啊!!!
T1
他们说很水,可是我竟然眼瞎考的时候没写

T2
数据范围有点大,暴力拿50咯

T3
有点思路,样例1也对了,可是爆0了

T4
什么鬼鬼


Day2

改题 i n g ing ing


T1

怪兽

题目
P Y W B K T D A PYWBKTDA PYWBKTDA最近正在打怪兽,一个斯拉夫神话中的凶猛怪兽,一个有着多个头的巨大龙状爬行
动物。
开始的时候,怪兽有 X X X个头,你有 n n n种打击方式。如果你选择第 i i i种打击方式,这个神奇的怪兽会减
m i n min min( d d d i i i , c u r cur cur)个头。这里 c u r cur cur表示当前怪兽拥有的头的数量。但是如果怪兽被打击以后还至少留下
了一个头,那么它就会再长出 h i h i hi 个头来。当 c u r cur cur = 0或者小于0的时候,怪兽被打败了。
注意,你可以使用任何一种打击方式任何次数,以任何的顺序。
例如,如果当前 c u r cur cur = 10, d d d = 7, h h h = 10,那么一次打击以后怪兽就会有13个头了(因为减少了7个头以后,怪兽还剩下3个头,再加上10个头)。但是如果当前 c u r cur cur = 10, d d d = 11, h h h = 100,那么怪兽就被打
败了。

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

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

样例
input 1
3 10
6 3
8 2
1 4

input 2
4 10
4 1
3 2
2 6
1 100

input 3
2 15
10 11
14 100

output 1
2

output 2
3

output 3
-1

数据范围限制
对于50%的数据,1 ≤ n ≤ 10,1 ≤ x ≤ 100,1 ≤ d i ≤ 100,1 ≤ h i ≤ 100。
对于100%的数据,1 ≤ n ≤ 100,1 ≤ x ≤ 109 ,1 ≤ d i ≤ 109 ,1 ≤ h i ≤ 109

提示
样例1,你可以使用第一种打击方式,第一次打击以后剩下(10-6+3=7)个头,再进行第2次打击。
样例2,你可以使用第一种打击方式,攻击3次。
样例3,这里你无法打败怪兽。

解题思路
第一种:
直接击败,d[i]>cur

第二种:
选用差最大的一种攻击
最后一次攻击用打击最大的那种

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,k,d,h,ans=0;
int b[120];
struct hhx{
	int s,d,h;
}a[120];
bool cmp(int x,int y)
{
	return(x>y);
}
int main()
{
	freopen("monster.in","r",stdin);
	freopen("monster.out","w",stdout);
    scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++)
	{
	    scanf("%d%d",&d,&h);
		if (d>k)  //可以直接打死
		{
		   cout<<1<<endl;
		   return 0;
	    }
	    b[i]=d;
	    if (d-h>0) //打击的比长出的多
	    {
	    	a[++ans].s=d-h;	
		    a[ans].d=d; 
		    a[ans].h=h;
		}
	}	
	if (ans==0)  //都是负减少并不能直接打败
	{
		cout<<-1<<endl;
		return 0;
	}
	sort(b+1,b+n+1,cmp);  //找到最大打击的数量
	for (int i=1;i<ans;i++)  //找到差最大的打击
	    for (int j=i+1;j<=ans;j++)
	        if (a[i].s<a[j].s)
	        {
	        	int c=a[i].s;
	        	a[i].s=a[j].s;
	        	a[j].s=c;
	        	c=a[i].d;
	        	a[i].d=a[j].d;
	        	a[j].d=c;
	        	c=a[i].h;
	        	a[i].h=a[j].h;
	        	a[j].h=c;
			}
	k-=b[1];  //最后一击
	if (k/a[1].s!=0)
	{
		if (a[1].s+k%a[1].s<=a[1].d) 
		   cout<<k/a[1].s+1;
		   else cout<<k/a[1].s+2;
	} 
	 else cout<<k/a[1].s+2;
	fclose(stdin);
	fclose(stdout);
	return 0;
} 

T2

白板

题目
P Y W B K T D A PYWBKTDA PYWBKTDA有一块白板,这块白板的四条边分别平行于坐标轴。我们可以假设这块白板的左
下角在( x x x 1 , y y y 1 )位置,右上角在( x x x 2 , y y y 2 )位置。
现在有两块黑板放到白板的上面,这两块黑板的四条边也是平行于坐标轴的。我们可以设第1块
黑板的左下角是( x x x 3 , y y y 3 ),右上角在( x x x 4 , y y y 4 )位置, 第2块黑板的左下角是( x x x 5 , y y y 5 ),右上角在( x x x 6 , y y y 6 )位置。

现在你的任务是来判断,我们从上往下看,是否有白板的部分区域可以被看到。所谓的白板部分
区域被看到的意思是,白板上至少有一个点没有被黑板遮住。

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

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

样例
input
3
2 2 4 4
1 1 3 5
3 1 5 5
3 3 7 5
0 0 4 6
0 0 7 4
5 2 10 5
3 1 7 6
8 1 11 7

output
NO
YES
YES
第一个例子中,白板被黑板完全覆盖。
第二个例子中,部分白板可以看到。比如(6.5,4.5)这个点就可以被看到。

数据范围限制
对于50%的数据:
0 ≤ x x x 1 < x x x 2 ≤ 100,0 ≤ y y y 1 < y y y 2 ≤ 100。
0 ≤ x x x 3 < x 4 ≤ 100,0 ≤ y y y 3 < y y y 4 ≤ 100。
0 ≤ x x x 5 < x 6 ≤ 100,0 ≤ y y y 5 < y y y 6 ≤ 100。

对于100%的数据:
1 ≤ t t t ≤ 100。
0 ≤ x x x 1 < x x x 2 ≤ 10 6 ,0 ≤ y y y 1 < y y y 2 ≤ 10 6 。
0 ≤ x x x 3 < x x x 4 ≤ 10 6 ,0 ≤ y y y 3 < y y y 4 ≤ 10 6 。
0 ≤ x x x 5 < x x x 6 ≤ 10 6 ,0 ≤ y y y 5 < y y y 6 ≤ 10 6 。

解题思路
第一种:
完全覆盖
白板分别和两块黑板判断
在这里插入图片描述
第二种:
上下覆盖
在这里插入图片描述
第三种:
左右覆盖
在这里插入图片描述
如果满足上面其中一种,输出 N O NO NO
都不满足,输出 Y E S YES YES
四个 i f if if 搞定

代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6;
void exchange()
{
	int c=x3;
	x3=x5;
	x5=c;
	c=y3;
	y3=y5;
	y5=c;
	c=y4;
	y4=y6;
	y6=c;
	c=x4;
	x4=x6;
	x6=c;
}
int main()
{
	freopen("sheet.in","r",stdin);
	freopen("sheet.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		scanf("%d%d%d%d",&x3,&y3,&x4,&y4);
		scanf("%d%d%d%d",&x5,&y5,&x6,&y6);
		if (x3>x5)
		   exchange();
		if (x3==x5&&y3>y5)
		   exchange();
		if (x3==x5&&y3==y5&&x6<x4)
		   exchange();
		if (x3==x5&&y3==y5&&x6==x4&&y6<x6)
		   exchange(); 
		 //保证黑板2比黑板3左
		if (x1>=x3&&y1>=y3&&x2<=x4&&y2<=y4)
        {
			cout<<"NO"<<endl;
			continue;
		}  //黑板2全覆盖白板1
		if ((x1>=x5)&&(y1>=y5)&&(x2<=x6)&&(y2<=y6))
		{
			cout<<"NO"<<endl;
			continue;
		}   //黑板3全覆盖白板1
		if ((x6>=x2)&&(y6>=y2)&&(x3<=x1)&&(y3<=y1)&&(y4>=y2)&&(y5<=y1)&&(x5<=x4))
		{
			cout<<"NO"<<endl;
			continue;
		}   //上下覆盖
		if ((x6>=x2)&&(y6>=y2)&&(x3<=x1)&&(y3<=y1)&&(x4>=x2)&&(x5<=x1)&&(y5<=y4))
		{
			cout<<"NO"<<endl;
			continue;
		}   //左右覆盖
		cout<<"YES"<<endl; //都不满足
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

后两题还没改,我努力

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值