2020.2.1普及C组模拟赛1

普及C组模拟赛1

纪中训练正式开始

1. 怪兽
题目描述

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。

样例输入

【输入样例1】
3 10
6 3
8 2
1 4
【输入样例2】
4 10
4 1
3 2
2 6
1 100
【输入样例3】
2 15
10 11
14 100

样例输出

【输出样例1】
2
【输出样例2】
3
【输出样例3】
-1

数据范围限制

对于50%的数据,1 ≤ n ≤ 10,1 ≤ x ≤ 100,1 ≤ d i ≤ 100,1 ≤ h i ≤ 100。
对于100%的数据,1 ≤ n ≤ 100,1 ≤ x ≤ 10 9 ,1 ≤ d i ≤ 10 9 ,1 ≤ h i ≤ 10 9 。

提示

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

正解
暴力出奇迹

AC代码

#include<iostream>
#include<cstdio>
using namespace std;
long long n,x,d,h,m,s,d1,h1,d2;
int main()
{
	freopen("monster.in","r",stdin);
	freopen("monster.out","w",stdout);
	cin>>n>>x;
	for(int i=1;i<=n;i++)
	{
		cin>>d>>h;
		if(d>=x){s=1;break;}//如果一下就能胜利,就直接退出
		if(d>h)if(d-h>m){m=d-h;d1=d;h1=h;}//找最大的
		d2=max(d,d2);
	}
	if(s==1)cout<<1;
	else
	if(m!=0)
	{
		s=1;
		if(x-d2<=0)m=0;
		x-=d1;
		while(x>0&&m!=0)//执行
		 {
			 x+=h1;//累加
			 if(x-d2<=0){s++;break;}//如果能直接打死,就打死
			 x-=d1;
			 s++;
		 }
		cout<<s;
	}
	else cout<<-1;
	fclose(stdin);
	fclose(stdout);
}

2.白板
题目描述

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。

样例输入

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

样例输出

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

数据范围限制

对于50%的数据:
0 ≤ x 1 < x 2 ≤ 100,0 ≤ y 1 < y 2 ≤ 100。
0 ≤ x 3 < x 4 ≤ 100,0 ≤ y 3 < y 4 ≤ 100。
0 ≤ x 5 < x 6 ≤ 100,0 ≤ y 5 < y 6 ≤ 100。
对于100%的数据:
1 ≤ t ≤ 100。
0 ≤ x 1 < x 2 ≤ 10 6 ,0 ≤ y 1 < y 2 ≤ 10 6 。
0 ≤ x 3 < x 4 ≤ 10 6 ,0 ≤ y 3 < y 4 ≤ 10 6 。
0 ≤ x 5 < x 6 ≤ 10 6 ,0 ≤ y 5 < y 6 ≤ 10 6 。
正解
暴力出奇迹

AC代码

#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;      
	 }
	fclose(stdin);
	fclose(stdout); 
}

3.序列
题目描述

PYWBKTDA最近在研究一些有趣的数列。
他给你一个无穷序列”112123123412345…”。这个序列是这么构造的,我们先写出1到1的所有整
数,然后写出1到2的所有整数,然后写出1到3的所有整数,这样不断重复进行到无穷。
例如现在前56个数字组成的序列是:
”11212312341234512345612345671234567812345678912345678910”。
我们把序列里面的每个数字从1开始编号,比如编号为1的数字就是1,编号为2的数字也是1,编号
为3的数字是2,编号为20的数字是5,编号为38的数字是2,编号56的数字是0.
现在你的任务是对于题目给出的q个询问,每个询问是k i ,表示问你编号为k i 的数字是多少。

输入

输入格式】
第一行是整数q,表示询问的数量。
接下来i行,每行一个整数,表示k i 。

输出

输出共计有q行,第i行的输出表示对应的k i 的询问,显然,每个答案都在0到9之间。

样例输入

【输入样例1】
5
1
3
20
38
56
【输入样例2】
4
2132
506
999999999
1000000000

样例输出

【输出样例1】
1
2
5
2
0
【输出样例2】
8
2
9
8

数据范围限制

对于30%的数据, 1 ≤ k i ≤ 10 5 。
对于70%的数据,1 ≤ k i ≤ 10 9 。
对于100%的数据,1 ≤ k i ≤ 10 18 ,1 ≤ q ≤ 500。
正解
暴力出奇迹

70分代码

#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
long long m,n,k,x,y,y1;
long long a[10000010];
string s;
int main(){
	freopen("squence.in","r",stdin);
	freopen("squence.out","w",stdout);
	int t;
	cin>>t;
	while(t--){
		cin>>k;
		y=0;
		a[1]=1;
		y1=0;
		while(y1+a[y+1]<k){
			y++;
			int xx=y+1;
			x=y+1;
			y1+=a[y];
			if(a[x]!=0)continue;
			if(x/1000000000!=0){ a[xx]=a[xx]+(x-999999999)*10;x=999999999; }
			if(x/100000000!=0){ a[xx]=a[xx]+(x-99999999)*9;x=99999999; }
			if(x/10000000!=0){ a[xx]=a[xx]+x*8-9999999*8;x=9999999; }
			if(x/1000000!=0){ a[xx]=a[xx]+x*7-999999*7;x=999999; }
			if(x/100000!=0){ a[xx]=a[xx]+x*6-99999*6;x=99999; }
			if(x/10000!=0){ a[xx]=a[xx]+x*5-9999*5;x=9999; }
			if(x/1000!=0){ a[xx]=a[xx]+x*4-999*4;x=999; }
			if(x/100!=0){ a[xx]=a[xx]+x*3-99*3;x=99; }
			if(x/10!=0){ a[xx]=a[xx]+x*2-9*2;x=9; }
			if(x/1!=0){ a[xx]=a[xx]+x; }
		}
		x=k-y1;
		long long i=0,j,k;
		while(x>0){
			i++;
			j=i,k=0;
			while(j!=0){
				k++;
				j=j/10;
			}
			x-=k;
		}
		x+=k;
		while(i!=0){
			char c=(i%10)+48;
			s=c+s;
			i=i/10;
		}
		cout<<s[x-1]<<endl;
		s="";
	}
	return 0;
}

4.游戏
题目描述

PYWBKTDA很喜欢玩一些游戏,比如算21点。他最近迷上了一款弹珠游戏。
有n个弹珠排成一排,第i个弹珠的颜色是a i 。 PYWBKTDA喜欢把这些弹珠重新排列,使得相
同颜色弹珠都在同一个连续区间。也就是说,如果PYWBKTDA想要把颜色i的全部放在一起,那
么颜色i弹珠的最左边的位置是l,最右边的位置是r,那么所有颜色为i的弹珠的位置只能在l到r之间,
l到r范围内也只能有颜色i的弹珠。
为了达到这个目的,PYWBKTDA将进行如下操作:找到两个相邻的弹珠,把它们交换一下位
置。
现在你的任务是来计算最小的交换次数,使得相同颜色弹珠都在同一区间,在这个区间内,同
种颜色的弹珠的位置是无关紧要的。

输入

输入的第一行是一个整数n,表示弹珠的数量。
输入的第二行有n个整数a i ,表示第i个位置上弹珠的颜色。

输出

输出只有一个整数,表示最少的交换次数。

样例输入

【输入样例1】
7
3 4 2 3 4 2 2
【输入样例2】
5
20 1 14 10 2
【输入样例3】
13
5 5 4 4 3 5 7 6 5 4 4 6 5

样例输出

【输出样例1】
3
【输出样例2】
0
【输出样例3】
21

数据范围限制

对于20%的数据,1 ≤ n ≤ 100,1 ≤ a i ≤ 2。
对于60%的数据,1 ≤ n ≤ 100000,1 ≤ a i ≤ 10。
对于100%的数据,1 ≤ n ≤ 100000,1 ≤ a i ≤ 20。

提示

样例1,在颜色序列[3,4,2,3,4,2,2]中,我们可以把第3个和第4个交换一下,然后把第2个和第3个交换
一下,最后把第4个和第4个交换一下。
正解
没有做出来
AC代码

待更新

赛后分析

1.
没加文件输入输出,后来AC
2.
没加文件输入输出,之后30分,经过修改AC
3.
不会,后来听讲解,70分
4.
不会,没做

谢谢观看

发布了49 篇原创文章 · 获赞 79 · 访问量 1627

猜你喜欢

转载自blog.csdn.net/weixin_45524309/article/details/104484284