0
点赞
收藏
分享

微信扫一扫

Codeforces Round #793 (Div. 2) A--D

独孤凌雪 2022-07-14 阅读 44

比赛地址:​​https://codeforces.com/contest/1682​​

A

思路:从中间往左右两侧入手,判断有组相同。

奇数中间的就是目标字符goal,往左右两边检查是否和goal相同。

偶数中间两个就是目标字符goal,往左右两边检查是否和goal相同

#define LOCAL
/*字符串 长n
计算i的数量,删掉了Si后仍然是回文序列
每一次只移除掉一个,看能移除掉几个满足回文
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define endl '\n'
using namespace std;
const int N = 1e9 + 5;

void s(){
int n ;cin >> n;

string a ; cin >> a;
a = " " + a;

long long ans = 0;
if(n % 2 == 1){
//odd
ans = 1;
char goal = a[n/2+1];
for(int i = n / 2 + 1 - 1, j = n / 2 + 1 + 1; i >= 1 && j <= n ; i --, j ++){
int tag = 1;
if(a[i] == goal){
ans++;
}else tag = 0;
if(a[j] == goal){
ans++;
}else tag = 0;

if(!tag) break;
}
}else{
//even
if(a[n/2] != a[n/2 + 1]) {
cout << ans << endl;
return ;
}
char goal = a[n/2];
for(int i = n / 2, j = n / 2 + 1; i >= 1 && j <= n; i -- , j ++){
int tag = 1;
if(a[i] == goal){
ans++;
}else tag = 0;
if(a[j] == goal){
ans++;
}else tag = 0;

if(!tag) break;
}
}

cout << ans << endl;
}

int main(){

cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

#ifdef LOCAL
cout << "\n记得更改input.txt!!!\n";
FILE *p = fopen("input.txt", "a+");
fclose(p);
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t; cin >>t;while(t-- )s();


return 0;
}

B

借鉴了​​https://zhuanlan.zhihu.com/p/518427683​​



/*
给你一个序列p 0---n-1只出现一次。最初序列没有排序

按位&
p满足xsort
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define endl '\n'
using namespace std;
const int N = 2e5 + 5;
int a[N], q[N];

void s(){
int n; cin >> n;


int x = -1;
rep(i, 0 , n-1){
cin >> a[i];
if(a[i] != i) x &= a[i];
}
cout << x << endl;

}

int main(){

cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

#ifdef LOCAL
cout << "\n记得更改input.txt!!!\n";
FILE *p = fopen("input.txt", "a+");
fclose(p);
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t; cin >> t;
while(t--) s();


return 0;
}

C

借鉴同上B


/*n个正数
lis(a) = 最长严格增加子序列
定义:a撇 为a倒叙后的序列
美丽数组被定为min(lis (a) , lis(a‘))
你的任务就是去决定美丽数组的最大值。你能够重新任意排序
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define endl '\n'
using namespace std;
const int N = 2e5 + 5;
int q[N], tt;
void s(){
int n ; cin >> n;

int a[N] = {};
map<int, int> mp;
rep(i, 1, n) cin >> a[i], mp[a[i]] ++;

sort(a + 1, a + 1 + n);
int len = unique(a+1, a+1+n) - a - 1;

int one = 0, two = 0;

rep(i,1,len){
if(mp[a[i]] >= 2) two++;
if(mp[a[i]] == 1) one++;
}

cout << two + (one + 1) / 2 << endl;
}

int main(){

cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

#ifdef LOCAL
cout << "\n记得更改input.txt!!!\n";
FILE *p = fopen("input.txt", "a+");
fclose(p);
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t; cin >>t; while(t--) s();


return 0;
}

D

借鉴同上B


/*
n个结点在一个圆圈里,从1---n顺时针顺序
给你一个二进制string长度n

你的任务就是构造一棵树,满足下面两个或者树不存在:
每一个结点i,结点的度如果si=0是偶数如果si = 1则为奇数
在圆圈里没有两条边连接。边允许连接圆圈

所有的边只是画一条线(无向边)

一棵树有n-1条边
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define endl '\n'
using namespace std;
const int N = 1e9 + 5;

void s() {
int n;
string s;
cin >> n >> s;

int onecnt = 0;
rep(i,0,n-1) onecnt += s[i] - '0';

if(onecnt&1 || onecnt == 0){
cout << "NO\n";return ;
}

cout << "YES\n";

int pos = s.find('1');
int last = s.find_last_of('1');

int pre = pos;//pre前
for(int i = pos + 1; i != last ; i ++){
if(s[i] == '1'){
cout << pre + 1 << " " << i + 1 << '\n';
pre = pos;
}
else {
cout << pre + 1 << " " << i + 1 << '\n';
pre = i;
}
}
for(int i = (pos - 1 + n) % n ; i != last -1; i = (i + n - 1) % n){
cout << pre + 1 << " " << i + 1 << '\n';
pre = i;
}

}


int main(){

cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

#ifdef LOCAL
cout << "\n记得更改input.txt!!!\n";
FILE *p = fopen("input.txt", "a+");
fclose(p);
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t; cin >> t; while(t--) s();


return 0;
}



举报

相关推荐

0 条评论