初二普及组全真模拟赛 前三题

1.数你太美【第一周】

题目描述

PB 获得了两个正整数数列 a i , b i {a_i} , {b_i} ai,bi,长度分别为 n , m n , m n,m ,其中每个数都小于 10 10 10。 定义一个正整数是“美丽的正整数”,当且仅当:这个数的十进制表示中,至少有一个 数位上的数在数列 a i a_i ai 出现过,至少有一个数位上的数在数列 b i b_i bi 出现过。现在 PB 希 望求出最小的“美丽的正整数”。

输入格式

第一行,两个正整数 n , m n , m n,m ;

第二行,n 个正整数,第 i i i 个为 a i a_i ai;

第三行,m 个正整数,第 i i i 个为 b i b_i bi

输出格式

一行,一个正整数表示最小的“美丽的正整数”。

样例

样例输入1
2 3
2 4
6 5 2
样例输出 1
2
样例解释 1

2 既在数列 a 中出现又在数列 b 中出现,且可知没有比 2 小的正整数是“美丽的正整 数”。

样例输入 2
2 6
8 7
1 1 4 5 1 4
样例输出 2
17
样例解释 2:

17 中有数位 1,7 。1 在数列 b 中出现, 7 在数列 a 中出现,且可以证明没有比 17 小 的正整数是“美丽的正整数”。

数据范围与提示

对于 30 % 30\% 30% 的数据, 1 ≤ n , m ≤ 4 1\le n,m\le4 1n,m4;
对于 100 % 100\% 100% 的数据, 1 ≤ n , m ≤ 9 , 1 ≤ a i , b i ≤ 9 1\le n,m\le 9,1\le a_i,b_i\le9 1n,m9,1ai,bi9

60分思路:

  • 求出数列 a,b 的最小值 mn1,mn2

  • mn1mn2相等,输出其中一个(样例1);

  • 否则先输出 m i n ( m n 1 , m n 2 ) min(mn1,mn2) min(mn1,mn2),再输出 m a x ( m n 1 , m n 2 ) max(mn1,mn2) max(mn1,mn2)。(样例2)

如果你是这样做的,那大概思路是莫得问题的了,但样例没给出,你就没想到数据可能长这样:

2 2
3 1
3 2

那么此时你的程序会输出 12 12 12,但是正确答案是 3 3 3

所以我们用2*9的数组visa,b中出现的数打标记,若 v i s [ x ] [ 0 ] & v i s [ x ] [ 1 ] vis[x][0]\&vis[x][1] vis[x][0]&vis[x][1],就可以输出x且结束程序了。

AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,x;
bool vis[10][2];
int mn1=9,mn2=9;
int main(){
	scanf("%d%d",&n,&m);
	while(n--){
		scanf("%d",&x);
		vis[x][0]=1;
		mn1=min(mn1,x);
	}
	while(m--){
		scanf("%d",&x);
		vis[x][1]=1;
		mn2=min(mn2,x);
	}
	for(int i=1;i<10;++i){
		if(vis[i][0]&vis[i][1]){
			printf("%d",i);
			return 0;
		}
	}
	printf("%d%d",min(mn1,mn2),max(mn1,mn2));
	return 0;
}

2.逃亡【第一周】

题目描述

从前有个平面直角坐标系,坐标系里有座学校。这是一个矩形,左下角是 ( 0 , 0 ) (0,0) (0,0),右上角是 ( n , m ) (n,m) (n,m)。有 k 个蒟蒻在校园中。第 i i i 个蒟蒻在 ( x i , y i ) (x_i,y_i) (xi,yi) 的位置。由于一些不可 抗因素,所有 x i x_i xi 互不相同,所有 y i y_i yi 互不相同。这时 PB 要来抓蒟蒻们做实验了!

蒟蒻们听到这个消息,也是四处逃亡,只要逃到校园的边界上就不会被 PB 抓到。 每个蒟蒻可以沿着任意路线逃亡。然而蒟蒻们反应迟钝,所以如果两个蒟蒻的逃亡路线 有交点,它们就有可能相撞,就会被 PB 抓住。所以任意两人的路线不能有交点。

现在蒟蒻们想知道,蒟蒻全部能成功逃亡的路线的长度之和的最小值。(虽然,这 对神通广大的 PB 根本不是一回事…)

输入格式

第一行三个整数 n , m , k n, m, k n,m,k,相邻两数用一个空格分开。

接下来 k k k 行,第 i i i 行两个正整数 x i x_i xi y i y_i yi,用一个空格分开。

输出格式

一行一个数表示总距离的最小值,保留 3 位小数

样例

样例输入

5 5 1
1 2

样例输出

1.000

数据范围与提示

对于前 30 % 30\% 30% 的数据, 0 ≤ n , m ≤ 6 , 1 ≤ k ≤ 5 0\le n,m\le6, 1\le k\le5 0n,m6,1k5

对于前 100 % 100\% 100% 的数据, 0 ≤ n , m ≤ 1 0 9 , 1 ≤ k ≤ 5000 , 1 ≤ x i < n , 1 ≤ y i ≤ m 0\le n,m\le10^9, 1\le k\le5000, 1\le x_i<n, 1\le y_i\le m 0n,m109,1k5000,1xi<n,1yim

对于所有数据, x i xi xi 互不相同, y i yi yi 互不相同。

呀!这题我怎么看不懂?换题!

(做完3题)

咦?对于所有数据, x i xi xi 互不相同, y i yi yi 互不相同?这不就是道入门题中的水题吗?

不就是求 x i − 0 , y i − 0 , n − x i , m − y i x_i-0,y_i-0,n-x_i,m-y_i xi0,yi0,nxi,myi 的最小值吗?

切了它!

#include<cstdio>
#include<algorithm>
using std::min;
int n,m,k,x,y;
double ans;
int main(){
	scanf("%d%d%d",&n,&m,&k);
	while(k--){
		scanf("%d%d",&x,&y);
		ans+=min(1.0*min(x,y),1.0*min(n-x,m-y));
	}
	printf("%.3lf",ans);
	return 0;
}

(代码量比第一题还少。。。)

(感觉那句保留3位小数就是个装饰。。。)

3.数数字【第一周】

题目描述

PB 带来了若干只蒟蒻。

众所周知,NTF 是数论学会的会长,于是 PB 准备用数字击败 NTF,以证明 PB 比 NTF 更强。

于是 PB 准备了一些卡片,并在每个蒟蒻头上都贴了一张卡牌。每个卡牌上都写了一个数字。

由于蒟蒻太弱了,甚至不会看镜子来了解自己头上的数字,但他们由于经常被大佬吊打,所以观察力敏锐,他们都知道别人头上的数字。

i i i 个蒟蒻会告诉你他看到了 a i a_i ai 种数字(定义两个数字不同种当且仅当它们的值不同)

但是由于蒟蒻太弱了,可能会报错数据,NTF 需要核实是否有一种情况使所有蒟蒻说的话都正确。(可能情况不唯一)

输入格式

多组测试,文件第一行一个整数 T T T,表示测试数据组数;

对于每组数据,第一行,一个整数 n n n,表示蒟蒻的数量;

第二行, n n n 个整数用空格隔开,表示数组 a i a_i ai,意义同题面。

输出格式

如果至少有一种情况使所有蒟蒻的话都正确,输出"yes",否则,输出"no"。

样例

样例输入

2
2
1 1
4
1 3 2 2

样例输出

yes
no

数据范围与提示

对于所有数据, T ≤ 10 T\le10 T10

对于 20% 的数据, n ≤ 8 n≤8 n8

对于所有数据, 1 ≤ n ≤ 1000000 , 0 ≤ a i < n 1\le n≤1000000, 0\le a_i<n 1n1000000,0ai<n

  • Step 1

    在输入时求出a中的maxmin

    (这数据貌似挺大,建议先把读优加上)

    开始分类讨论。

  • Step 2

    如果 m a x − m i n ≥ 2 max-min\ge2 maxmin2,就可以愉快地输出"no"了。

    why?

    最坏的情况也不过就是蒟蒻A和其他蒟蒻头上的数字都是x,蒟蒻B是y,蒟蒻A会比蒟蒻B多看到一个数值,如果A比B多看到了一个以上,就不可能了。

  • Step 3

    如果 m a x = = m i n max==min max==min

    • Step 3-1

      第一种可能性,全部蒟蒻头上的数都是同一个,也就是 m a x = = 1 max==1 max==1,输出"yes"。

    • Step 3-2

      第二种可能性,全部蒟蒻头上的数都不同,也就是 m a x = = n − 1 max==n-1 max==n1,输出"yes"。

    • Step 3-3

      第三种可能性, m a x × 2 ≤ n max×2\le n max×2n,输出"yes"。

      why?

      设除蒟蒻A头上的数 x x x唯一外,其他蒟蒻头上的数值的数量均 ≥ 2 \ge2 2

      那么除了蒟蒻A外,其他所有蒟蒻都可以看到自己的"友军"头上的数和其他所有数,但是蒟蒻A没有"友军",所以会比其他蒟蒻少看到一个数,与 m a x = = m i n max==min max==min 的条件矛盾。

      所以,每个数值的数量必须 ≥ 2 \ge2 2

      而由于每个蒟蒻都可以看见max种数,得出max就是所有数的种类数,所以最少有 2 × m a x 2×max 2×max 个数,也就是 2 × m a x 2×max 2×max 个蒟蒻,而蒟蒻总数为n,所以 m a x × 2 max×2 max×2 必须 ≤ n \le n n

    • else

      输出"no"。

  • Step 4

    我们在Step 1输入的时候算出和min相等的值x,也就是说,有 x个蒟蒻头上的值是唯一的,那么,除去这x个蒟蒻以外的 n − x n-x nx 个蒟蒻头上的值的数量都 ≥ 2 \ge2 2

    是不是很眼熟?我们想起了我们在Step 3-3所得到的结论:当 m a x = = m i n max==min max==min时,所有数值的数量 ≥ 2 \ge 2 2 2 × m a x ≤ n 2×max\le n 2×maxn,而此时的不等式中的n就是 n − x n-x nx,但不等式中的max是多少呢?

    max是看见的x个无"友军"蒟蒻和剩余的数值个数的和——

    那么,只要把x减去,剩余的,不就是数量 ≥ 2 \ge2 2的数值种类和了吗?

    所以我们得到了: ( m a x − x ) ∗ 2 < = n (max-x)*2<=n (maxx)2<=n

    又∵max总不可能是个非正整数,所以max应该 > x >x >x

    若同时满足上面两个条件,就可以输出"yes"了,否则输出"no"。

奇怪的发际线上升了!

代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,mn,mx,x,a[1000005];
inline void read(int&x){
	x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
	return;
}
int main(){
	read(T);
	while(T--){
		mx=0,mn=1000005;
		read(n);
		for(int i=1;i<=n;++i){
			read(a[i]);
			if(a[i]<mn){
				x=0;
				mn=a[i];
			}
			else if(mn==a[i])
				x++;
			mx=max(mx,a[i]);
		}
		if(mx-mn>=2){
			puts("no");
			continue;
		}
		if(mn==mx){
			if(mx+1==n||mx==1||(mx<<1)<=n)
				puts("yes");
			else puts("no");
		}
		else{
			if(((mx-x)<<1)<=n-x&&x<mx)
				puts("yes");
			else puts("no");
		}
	}
	return 0;
}

看看咱这次的赞能不能突破……0个吧、、、

posted @ 2020-09-12 20:10  XSC062  阅读(70)  评论(0编辑  收藏  举报