这篇博客大致整理了选拔赛剩余的一些题目
链接:https://ac.nowcoder.com/acm/contest/9564/C
来源:牛客网
1.2.
题目描述
蒲煜凡学长最近迷上了一个漂亮的小学妹,他想送一朵特别的花给这个小学妹。
他现在有一把N朵漂亮的花,每多花都有a[i]个花瓣,如果有1朵花的花瓣数与其他任意一朵花的花瓣数之差等于2,那么他可以选择把这朵花扔掉,也可以选择丢弃。
请问经过若干次操作之后蒲煜凡学学长能找到唯一的一支特别的花送给小学妹吗?
输入描述:
第一行一个整数t(1<=t<=500)表示测试样例数
每个测试样例第一行一个整数n(1<=n<=1e4)表示花的数量,第二行n个整数ai表示花瓣数。
输出描述:
输出t行"YES"or"NO"
示例1
输入
复制
1
4
2 4 6 8
输出
复制
YES
示例2
输入
复制
1
5
9 3 5 6 7
输出
复制
NO
思路:首先,我们分析题意可以发现,先将花瓣数列进行排序,如果两端的花不能被消去,那么,就肯定找不到唯一的一朵花,而且当n=1时肯定有唯一的花朵,当n不等于一时我们首先需要考虑花瓣中有无重复的数字,如果有重复的数字我们肯定要进行去重,因为只有数据中留有这个数据且能够消去,那么重复的花瓣都能消去,然后我们再进行遍历,看看最后能否只剩下一朵花。
代码如下:
#include <stdio.h>
#include <algorithm>
#include <map>
using namespace std;
long int a[10000],b[10000];
map<int,int>d;
int main(){
long int t;
scanf("%ld",&t);
while(t--){
d.clear();
long int n;
scanf("%ld",&n);
if(n==1){
printf("YES\n");
continue;
}
int j=0;
for(int i=0;i<n;i++){
scanf("%ld",&a[i]);
d[a[i]]++;
if(d[a[i]]==1){
b[j]=a[i];
j++;
}
}
sort(b,b+j);
if(j==1){
printf("NO\n");
continue;
}
int count = 0;
for(int i=0;i<j-1;i++){
if(b[i+1]-b[i]!=2)
count=1;
}
if(count==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/9564/F
来源:牛客网
题目描述
徐利峰大魔王抢走了蒲煜凡学长刚交的npy,回到了自己的王国,为了npy,蒲煜凡学长是不会善罢甘休的,恰巧蒲煜凡学长刚学会了影分身之术,他决定打败徐利峰大魔王,夺回npy,不过蒲煜凡学长的影分身之术还不太熟练,他不知道自己要变幻出多少个影分身才能确保一定能找到徐利峰大魔王
徐利峰大魔王的王国错综复杂,已知王国中有n个的城市,m条通路(无向边),为了蒲煜凡学长的未来,请你编写一个程序确定他的分身数目。
输入描述:
第一行城市数量n(1<=n<=1e5),通路的条数m(0<=m<=1e5),城市中可能有重边和自环
下面m行每行包含两个整数x和y,表示x和y之间存在一条通道
输出描述:
输出最少需要多少个影分身
示例1
输入
复制
5 4
1 4
2 4
4 2
2 2
输出
复制
3
一道很基础的并查集
首先初始化根节点,输入数据时,就将两个城市连在一个父节点上此时,两城市连通,需要的影子数就减一,如果两个城市已经在一个根节点上或者自身与自身相连则影子数不变。
代码如下:
#include<stdio.h>
int n,m;
int fa[1000010];
int find(int x)
{
if(fa[x]!=x)
fa[x]=find(fa[x]);
return fa[x];
}
int main(){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
fa[i]=i;
while(m--)
{
int a,b;
scanf("%d %d",&a,&b);
int pa=find(a),pb=find(b);
if(pa!=pb){
fa[pa]=pb;
n--;
}
}
printf("%d",n);
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/9564/G
来源:牛客网
题目描述
大多数情况下甘靖学长说普通话时都很标准,但有时却令人抓狂,这件事困扰他很久了,突然有一天,他想通过读数字来纠正他的发音,
但是他不想按正常的顺序读数字,于是他按照某种规律写了一些数字在黑板上,比如如果他想数到9,那么他会把数字写成如下格式:
1 2 6 7
3 5 8
4 9
如果他想数到15,那么他会把数字写成如下格式:
1 2 6 7 15
3 5 8 14
4 9 13
10 12
11
他突然发现他写数字的规律是个蛇形,具体描述是这样的:
对于每一条左下-右上的斜线,从左上到右下依次编号1,2,…,2n-1;按编号从小到大的顺序,将数字从小到大填入各条斜线,其中编号为奇数的从左下向右上填写,编号为偶数的从右上到左下填写
输入描述:
输入一个不大于10000的正整数n,表示要填充到的数字的大小
输出描述:
按规律输出这些数字,相邻两个元素之间用单个空格间隔
示例1
输入
复制
50
输出
复制
1 2 6 7 15 16 28 29 45 46
3 5 8 14 17 27 30 44 47
4 9 13 18 26 31 43 48
10 12 19 25 32 42 49
11 20 24 33 41 50
21 23 34 40
22 35 39
36 38
37
这道题是一道很好的思维题,听zzx聚聚的一番讲解后才明白了思路,并且聚聚的思路特别巧妙!!
首先我们要存入这个数组,这个数组有多大?我们通过数学方法可以算出至少要用215个元素的二维数组。所以我们要开一个二维数组,来存数字,存数字的过程中,我们把整个阵看作一个类似斜着放置的金字塔,根据每行的规律存入数字,最后再按照奇偶的顺序输出。
代码如下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int a[220][220], n, count = 0;
int main() {
scanf_s("%d", &n);
int i, j = 0;
for (i = 1; j < n; i++) {
j += i;
count++;//斜金字塔行数
}
int l = 0;
for (i = 1; i <= count; i++) {
for (int k = 1; k <= i; k++) {
if (i % 2 == 1)//在这里判断奇偶并且存入数字
a[i + 1 - k][k] = ++l;
else
a[k][i + 1 - k] = ++l;
if (l == n)
break;
}
}
for (i = 1; i <= count; i++) {
if (i > 1)
printf("\n");
int m = 1;
while (a[i][m])
printf("%d ", a[i][m++]);
}
}
选拔赛的整理在这就告一段落了,加油!期末人!