牛客周赛 Round 52
A 两数之和
链接:https://ac.nowcoder.com/acm/contest/86373/A
来源:牛客网
题目描述
对于给定的正整数 𝑧 ,你需要寻找两个不同的正整数 𝑥 和 𝑦 ,使得 𝑥+𝑦=𝑧 成立。
如果不存在这样的 𝑥 和 𝑦 ,你只需要输出 NO 。
输入描述:
在一行上输入一个整数 𝑧 (1≤𝑧≤2⋅10^5^) 。
输出描述:
如果存在符合要求的答案,你需要先输出 YES ,随后在第二行上输出两个正整数 𝑥 和 𝑦 代表你的答案;否则,直接输出 NO 。
示例1
输入
2
输出
NO
示例2
输入
3
输出
YES
1 2
题解
这玩意1和2不行,剩下都行,原因?没有!
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int i,j,k;
int z;
cin>>z;
if(z==1||z==2)cout<<"NO"<<endl;
else printf("YES\n1 %d\n",z-1);
return 0;
}
B 小红装匣子
链接:https://ac.nowcoder.com/acm/contest/86373/B
来源:牛客网
题目描述
小红有 𝑎 块 1×2 大小的物块,𝑏 块 1×3 的大小的物块,小红想知道能不能填满 2×𝑛 大小的匣子。
物块可以旋转使用,可以有剩余。
输入描述:
每个测试文件均包含多组测试数据。第一行输入一个整数 𝑇 (1≤𝑇≤10^5^) 代表数据组数,每组测试数据描述如下:
在一行上输入三个整数 𝑎,𝑏 和 𝑛 (0≤𝑎,𝑏≤2×10^9^;1≤𝑛≤2×10^9^) 表示有 𝑎 块1×2 大小的物块,𝑏 块 1×3 的大小的物块,匣子的大小为 2×𝑛。
输出描述:
对于每一组测试数据,如果存在一种方式使得物块可以填满匣子,在一行上输出 YES ;否则,直接输出 NO 。
示例1
输入
1
3 2 6
输出
YES
说明
其中一种可行的放置方式如下图所示:
题解
需要一点点一点点数学,你看特殊情况嘛,A是可以竖着排列的,B只能横着,所以把B的个数/2就是可以完整的排列的各自,然后你看A的数量和剩余的格子的数量就完事了。
cpp
#include<bits/stdc++.h>
using namespace std;
int t,a,b,n;
signed main(){
int i,j,k;
cin>>t;
while(t--){
cin>>a>>b>>n;
b/=2;
n = max(n%3,n-b*3);
if(a>=n) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
C 小红的数字对对碰
链接:https://ac.nowcoder.com/acm/contest/86373/C
来源:牛客网
题目描述
小红有一个长度为 𝑛 的数组 𝑎 ,第 𝑖 位的值为 𝑎𝑖 。她想通过以下方式,尽可能地减少数组长度。
● 当 𝑙𝑒𝑛(𝑎)>1 且存在二元组 (𝑖,𝑗) ,满足 𝑖<𝑗 且 𝑎𝑖+𝑎𝑗≤0 ,则可消去
𝑎𝑖 和 𝑎𝑗 。
● 当 𝑙𝑒𝑛(𝑎)>1 且存在二元组 (𝑖,𝑗) ,满足 𝑖<𝑗 且 𝑎𝑖⊕𝑎𝑗≤0 ,则可消去
𝑎𝑖 和 𝑎𝑗 。
请你输出最小化后的数组的长度。
⊕ 表示按位异或,数字以 32 位补码形式存储。
输入描述:
第一行输入一个整数 𝑛 ( 1≤𝑛≤10^5^) 代表初始元素数量。
第二行输入 𝑛 个整数 𝑎1,𝑎2,...,𝑎𝑛 (−10^9^≤𝑎𝑖≤10^9^) 代表初始的数组。
输出描述:
在一行上输出一个整数,代表最小化后的数组的长度。
示例1
输入
5
-3 -1 0 2 4
输出
1
说明
𝑎1 和 𝑎4 按照方式一消除。𝑎2 和 𝑎5 按照方式二消除。
题解
找规律,如果异或运算这些学习的足够好应该能秒。
试验下能发现负数和正数异或为负数
所以后面就好办了
- 先把除了负数以外的相同的数两两异或消去
- 剩下的数再用负数两两异或消去
- 如果还剩下负数,就让负数两两相加消去
cpp
#include<bits/stdc++.h>
using namespace std;
int n,c;
int main()
{
int i,j,k;
cin >> n;
map<int, int> mp;
for (i = 1; i <= n; i ++) {
int x;cin >> x;
if (x < 0) c ++;
else mp[x] ++;
}
int ans = n;
int cc = 0;
for (auto [x, y] : mp) {
ans -= (y / 2) * 2;
cc += y % 2;
}
if (c >= cc) {
ans -= cc * 2 + (c - cc) / 2 * 2;
} else {
ans -= c * 2;
}
cout << ans << '\n';
return 0;
}
D 小红的最大字典序
链接:https://ac.nowcoder.com/acm/contest/86373/D
来源:牛客网
题目描述
小红有 𝑛 个数字 𝑎1,𝑎2,...,𝑎𝑛 和一个空字符串 𝑠 ,现在她需要执行
𝑛 次操作:第 𝑖 次操作需要将 𝑎𝑖 按照数位上的相对顺序、从左到右的取出并依次插入 𝑠 (在 𝑠 中不需要连续,但需要保持原有相对顺序)。
小红想要构造一个这样的字符串 𝑠 ,使得它的字典序是所有合法构造方案中最大的。
输入描述:
第一行输入一个整数 𝑛 (1≤𝑛≤10^5^) 代表数字个数。
第二行输入 𝑛 个整数 𝑎1,𝑎2,...,𝑎𝑛 (1≤𝑎𝑖≤10^9^ ) 代表数组中的元素。
除此之外,保证所有的数字数位长度之和 ∑ i = 1 n l e n ( a i ) \sum_{i=1 }^{n}len(ai) ∑i=1nlen(ai) 不超过 2⋅10^5^ 。
输出描述:
在一行上输出一个长度为 ∑ i = 1 n l e n ( a i ) \sum_{i=1 }^{n}len(ai) ∑i=1nlen(ai) ,且只由数字组成的字符串 𝑠 ,代表字典序最大的构造答案。
示例1
输入
2
92 86
输出
9862
说明
一共有六种合法构造方案:8692、8962、8926、9862、9826、9286。
示例2
输入
2
912 215
输出
921512
题解
额,没想出来,看完题解写的
cpp
#include<bits/stdc++.h>
using namespace std;
string s;
priority_queue<string> q;
int main(){
cin>>s;
while(cin>>s)q.push(s);
while(q.top()!=""){
s=q.top(); q.pop(); cout<<s[0];
q.push(s.substr(1));
}
return 0;
}
E 小红的图上加边
链接:https://ac.nowcoder.com/acm/contest/86373/E
来源:牛客网
题目描述
小红有一张 𝑛 个点 𝑚 条边的无向图,每个节点的权值是 𝑎𝑖 。
现在小红希望加边把这个图连成连通图,每次连接的代价是新形成的联通块的最大元素值,小红想知道最小需要消耗多少代价可以把这个图连成连通的。
输入描述:
第一行输入两个整数𝑛 和 𝑚 (1≤𝑛≤10^5^; 0≤𝑚≤10^5^) 表示点数和边数。
第二行输入 𝑛 个整数 𝑎1,𝑎2,...,𝑎𝑛 (1≤𝑎𝑖≤10^9^) 表示每个节点的权值。
接下来 𝑚 行,第 𝑖 行输入两个整数 𝑢𝑖 和 𝑣𝑖 (1≤𝑢𝑖,𝑣𝑖≤𝑛) 表示无向图上第 𝑖 条边连接节点 𝑢𝑖 和 𝑣𝑖 ,保证没有重边。
输出描述:
在一行上输出一个整数,表示最小需要消耗的代价。
示例1
输入
5 3
1 2 3 4 5
1 2
2 3
1 3
输出
9
说明
先加上 (1,4) 这条边,代价是 4,然后加上 (1,5) 这条边,代价是 5,总代价是 9。
F 小红的括号串
链接:https://ac.nowcoder.com/acm/contest/86373/F
来源:牛客网
题目描述
小红有一个只包含 '(' 、')' 和 '?' 的字符串,小红想知道有多少种将 '?' 替换成 '(' 或 ')' 的方式使得存在一种循环移位、让该字符串为合法的括号串。
假设一个长度为 𝑛 的字符串 𝑠[𝑘:𝑛]+𝑠[1:𝑘) 是字符串 𝑠 的循环移位,且 𝑠[𝑘:𝑛]+𝑠[1:𝑘) 是一个合法的括号串,那么字符串 𝑠 符合题目要求。
输入描述
第一行输入一个整数 𝑛 (1≤𝑛≤10^5^) 代表字符串长度。
第二行输入一个长度为 𝑛 ,且只由 '(' 、')' 和 '?' 三种字符组成的字符串 𝑠 。
输出描述:
在一行上输出一个整数,代表合法替换方式数量。由于答案可能很大,你需要输出答案对
10^9^+7 取模的结果。
示例1
输入
10
()(??(?)??
输出
10
说明
其中一种替换方式为:()())())((,可以循环移位得到 ((()())()),是合法的括号串。