A
点击此处查看对应的题目.
本题涉及算法:位运算
本题的位运算操作可以无限次,且要将答案尽可能小,利用与运算的性质只要将所有值全部取&即可。(与运算的性质:两个数相与结果必然是0或是其中最小的值)
时间复杂度 O ( n ) O(n) O(n)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 110,INF = 1e9;
int a[N];
int n;
void solve()
{
cin >> n;
for(int i = 0;i < n;i ++){
cin >> a[i];
}
int res = a[0];
for(int i = 1;i < n;i ++){
res =res & a[i];
}
cout << res <<'\n';
}
int main()
{
int t;
cin >> t;
while(t --){
solve();
}
return 0;
}
B
点击此处查看对应的题目.
本题涉及算法:贪心
本题需要尽可能使字符串不重复,所以我们可以找到第一个已知的字符,然后向两边不重复地将位置字符添加上即可。如果找不到已知字符就直接依次输出‘B’和‘R’即可。
时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 110,INF = 1e9;
int a[N];
int n;
string s;
void output()
{
for(int i = 0;i < s.size();i ++)
if(a[i] == 0) cout << 'B';
else cout <<'R';
puts("");
}
void solve()
{
int n;bool st = true;
cin >> n >> s;
for(int i = 0;i < s.size();i ++){
if(s[i] == 'B') {a[i] = 0;st = false;}
else if(s[i] == 'R') {a[i] = 1;st =false;}
else if(s[i] == '?') a[i] = -1;
}
if(st == true){
for(int i = 0;i < n;i ++){
if(i & 1) cout<<'B';
else cout << 'R';
}
puts("");
return;
}
for(int i = 0;i < s.size();i ++){
if(a[i] == 1 || a[i] == 0){
for(int j = i - 1;j >= 0;j --){
if(a[j] == -1) a[j] = a[j + 1] ^ 1;
}
for(int k = i + 1;k < s.size();k ++){
if(a[k] == -1) a[k] = a[k - 1] ^ 1;
}
break;
}
}
output();
}
int main()
{
int t;
cin >> t;
while(t --){
solve();
}
return 0;
}
C
点击此处查看对应的题目.
本题模拟
本题需要先特判第一个点,如果第一个点为1就都可以走出一条路。然后特判最后一个点,最如果是0也就都可以走得通。没有特判的正常情况下只要中间的点有0,那么就可以形成路径。我当时做的时候居然判断用if了好几次QAQ
时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4 + 10,INF = 1e9;
int a[N];
void output(int n)
{
for(int i = 1;i <= n;i ++) cout << i << " ";
}
void solve()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++) cin >> a[i];
if(a[1]){
cout << n + 1 << " ";
for(int i = 1 ; i <= n ; i ++) cout << i << " ";
puts("");
return;
}
if(!a[n]){
for(int i = 1 ; i <= n + 1; i ++) cout << i << " ";
puts("");
return;
}
for(int i = n - 1 ; i >= 1 ; i--)
if(!a[i]){
for(int j = 1 ; j <= i ; j++){
cout << j << " ";
}
cout << n + 1 << " ";
for(int j = i + 1 ; j <= n ; j++){
cout << j << " ";
}
puts("");
return;
}
}
int main()
{
int t;
cin >> t;
while(t --){
solve();
}
return 0;
}
D1
点击此处查看对应的题目.
本题算法:路径压缩
本题数据结构:并查集
本题应先将输入值存入并查集,然后查询每两个点的根节点是否相同,如果根节点不相同则说明这两个值不在同一个树中,需要连接起来,接下来将这两个值链接并记录下来即可。
看了codeforces的题解,发现并查集压缩路径的另一种写法,这里也写一下
int get_tree(int id, int x)
{
return x == tree[id][x] ? x : tree[id][x] = get_tree(id, tree[id][x]);
}
时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010,INF = 1e9;
int tree[2][N];
vector<PII> cnt;
int get_tree(int id, int x)//并查集
{
if(x != tree[id][x]) tree[id][x] = get_tree(id,tree[id][x]);
return tree[id][x];
}
int main()
{
int n,m1,m2;
cin >> n >> m1 >> m2;
for(int i = 1;i <= n;i ++) tree[0][i] = tree[1][i] = i;
while(m1 -- ){
int a,b;
cin >> a >> b;
a = get_tree(0,a),b = get_tree(0,b);
tree[0][a] = b;
}
while(m2 --){
int a,b;
cin >> a >> b;
a = get_tree(1,a),b = get_tree(1,b);
tree[1][a] = b;
}
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= n;j ++){
if(i == j) continue;
if(get_tree(0,i) != get_tree(0,j) && get_tree(1,i) != get_tree(1,j)){
cnt.push_back({i,j});
tree[0][get_tree(0,i)] = get_tree(0,j);
tree[1][get_tree(1,i)] = get_tree(1,j);
}
}
cout << cnt.size() <<'\n';
for(int i = 0;i < cnt.size();i ++) cout << cnt[i].first << " " << cnt[i].second << '\n';
return 0;
}