初二普及组全真模拟赛 前三题
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 1≤n,m≤4;
对于 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 1≤n,m≤9,1≤ai,bi≤9 。
60分思路:
-
求出数列 a,b 的最小值 mn1,mn2;
-
若 mn1与mn2相等,输出其中一个(样例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的数组vis给a,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 0≤n,m≤6,1≤k≤5。
对于前 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 0≤n,m≤109,1≤k≤5000,1≤xi<n,1≤yi≤m
对于所有数据, 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 xi−0,yi−0,n−xi,m−yi 的最小值吗?
切了它!
#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 T≤10
对于 20% 的数据, n ≤ 8 n≤8 n≤8
对于所有数据, 1 ≤ n ≤ 1000000 , 0 ≤ a i < n 1\le n≤1000000, 0\le a_i<n 1≤n≤1000000,0≤ai<n
-
Step 1
在输入时求出a中的max和min
(这数据貌似挺大,建议先把读优加上)
开始分类讨论。
-
Step 2
如果 m a x − m i n ≥ 2 max-min\ge2 max−min≥2,就可以愉快地输出"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==n−1,输出"yes"。
-
Step 3-3
第三种可能性, m a x × 2 ≤ n max×2\le n max×2≤n,输出"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 n−x 个蒟蒻头上的值的数量都 ≥ 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×max≤n,而此时的不等式中的n就是 n − x n-x n−x,但不等式中的max是多少呢?
max是看见的x个无"友军"蒟蒻和剩余的数值个数的和——
那么,只要把x减去,剩余的,不就是数量 ≥ 2 \ge2 ≥2的数值种类和了吗?
所以我们得到了: ( m a x − x ) ∗ 2 < = n (max-x)*2<=n (max−x)∗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个吧、、、
—— · EOF · ——
真的什么也不剩啦 😖