A. Technical Support
题目大意:
每次一个问题Q,和一个回答A。要求每个问题Q后面都有A与之对应,问给出的字符串是不是满足这个条件
分析:
模拟就行了
#include <bits/stdc++.h>
using namespace std ;
const int N = 108 ;
void solve(){
int n ;
cin >> n ;
string s ;
cin >> s ;
int cnt = 0 ;
for(int i = 0 ; i < n ; i ++){
if(s[i] == 'Q') cnt ++ ;
else {
if(cnt) cnt -- ;
}
}
if(cnt) cout << "No" << '\n' ;
else cout << "Yes" << '\n' ;
}
int main(){
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while(T --){
solve() ;
}
return 0;
}
B. Kevin and Permutation
题目大意:
有一个只包含元素1~n的序列,要求你构造出来的序列使得的值最大
分析:
我们可以观察大,最大值就是,构造方法为n , n/2 , n - 1 , n/2 - 1 ...这样一直构造下去,如果长度是奇数,就将n放在序列的最后
#include <bits/stdc++.h>
using namespace std ;
const int N = 108 ;
void solve(){
int n ;
cin >> n ;
if(n % 2 == 1){
for(int i = n / 2 , j = n - 1 ; i >= 1 ; i -- , j --){
cout << i << ' ' << j << ' ' ;
}
cout << n << '\n' ;
}else{
for(int i = n / 2 , j = n; i >= 1 ; i -- , j --){
cout << i << ' ' << j << " \n"[i == 1] ;
}
}
}
int main(){
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while(T --){
solve() ;
}
return 0;
}
C1. Make Nonzero Sum (easy version)
题目大意:给定一个数组,你可以将数组进行不同的分组,并且每一组区间[l,r]的价值为:,要求你给出一个合法的分组满足所有分组的价值之和为0
分析:
我们首先注意到一个性质:如果当前每个区间的长度都为一,也就是每个数自己和自己是一组,那么如果找到一个数是1,并且把它跟前面的一个数并成一组,那么1就变成了-1,那么对所有价值的和的贡献就是-2。同理,如果当前的数是-1,把它与前面一个数合并成一组,那么-1就变成了+1,对所有价值的和的贡献是+2。也就是说我们每次合并一个分组本质上就是对价值的+2或者-2操作。所以我们的策略是,首先我们将所有数单独分成一个组,如果价值是奇数,那么就一定不行输出-1;如果是偶数,那么会有总价值>0总价值<0和总价值==0之分:
1.如果总价值大于0,我们就在序列里面找到1的位置并且把它和前面一个数合并,直到总价值为0
2.如果总价值==0,直接输出每一个单个区间即可
3.如果总价值<0,我们就在序列里面找-1的位置并且把它和前面一个数合并,直到总价值为0
#include <bits/stdc++.h>
using namespace std ;
const int N = 200008 ;
int a[N] ;
struct node{
int l , r ;
}no[N] ;
void solve(){
int n ;
cin >> n ;
int tot = 0 ;
for(int i = 1 ; i <= n ; i ++){
cin >> a[i] ;
}
if(n & 1){
cout << -1 << '\n' ;
return ;
}
for(int i = 1 ; i < n ; i ++){
if(a[i] == a[i + 1]){
no[tot].l = i , no[tot ++].r = i + 1 ;
i ++ ;
}else{
no[tot].l = i , no[tot ++].r = i ;
no[tot].l = i + 1 , no[tot ++].r = i + 1 ;
i ++ ;
}
}
cout << tot << '\n' ;
for(int i = 0 ; i < tot ; i ++){
cout << no[i].l << ' ' << no[i].r << '\n' ;
}
}
int main(){
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while(T --){
solve() ;
}
return 0;
}
C2. Make Nonzero Sum (hard version)
题目大意:
题目意思和上题一致,只是序列中出现了0的情况
分析:
我们可以发现0怎么变都不会对总价值产生贡献,所以我们还是按照C1的思路解决即可
#include <bits/stdc++.h>
using namespace std ;
const int N = 200008 ;
int a[N] ;
bool vis[N] ;
bool tmp[N] ;
void solve(){
memset(vis , false , sizeof vis) ;
memset(tmp , false , sizeof tmp) ;
int n ;
// puts("-------------------") ;
cin >> n ;
int sum = 0 ;
for(int i = 1 ; i <= n ; i ++){
cin >> a[i] ;
sum += a[i] ;
}
if(sum & 1) {
cout << -1 << '\n' ;
return ;
}
if(sum == 0){
cout << n << '\n' ;
for(int i = 1 ; i <= n ; i ++){
cout << i << ' ' << i << '\n' ;
}
return ;
}
int cnt = n ;
if(sum > 0){
for(int i = 2 ; i <= n ; i ++){
if(a[i] == 1 && !tmp[i - 1]){
// cout << i << '\n' ;
sum -= 2 ;
vis[i - 1] = true ;
tmp[i] = tmp[i - 1] = true ;
cnt -- ;
}
if(sum == 0) break ;
}
}else if(sum < 0){
for(int i = 2 ; i <= n ; i ++){
if(a[i] == -1 && !tmp[i - 1]){
sum += 2 ;
vis[i - 1] = true ;
tmp[i] = tmp[i - 1] = true ;
cnt -- ;
}
if(sum == 0) break ;
}
}
cout << cnt << '\n' ;
for(int i = 1 ; i <= n ; i ++){
if(vis[i]){
cout << i << ' ' << i + 1 << '\n' ;
i ++ ;
continue ;
}
cout << i << ' ' << i << '\n' ;
}
}
int main(){
// std::ios::sync_with_stdio(false) ;
// std::cin.tie(0) ;
int T ;
cin >> T ;
while(T --){
solve() ;
}
return 0;
}
D. Factorial Divisibility
题目大意:
给定一个n和x,和一个长度为n的数组,判断能不能被整除
分析:
我们可以注意到,例如 ,也就是4个3!能够被四整除,也就是说,如果以第i个数为例,如果i-1的个数是i的倍数,那么就所有的i-1加起来就可以被i整除,一下面的例子来理解:
#include <bits/stdc++.h>
using namespace std ;
const int N = 5e5 + 8 ;
map<int,int> mp ;
int a[N] ;
void solve()
{
int n , k ;
cin >> n >> k ;
for(int i = 1 ; i <= n ; i ++) {
cin >> a[i] ;
mp[a[i]] ++ ;
}
for(int i = 1 ; i < k ; i ++){
if(mp[i] % (i + 1) == 0)
mp[i + 1] += mp[i] / (i + 1) ;
else {
puts("NO") ;
return ;
}
}
puts("YES") ;
}
int main(){
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
solve() ;
return 0;
}
EF太菜了不会
水平有限,欢迎指正