codeforce #624 div3
传送门
A. Add Odd or Subtract Even
题意
给定\(a\),\(b\),通过对\(a\)的操作使得\(a,b\)相等,只能加奇数,减偶数,至少需要多少次操作
数据范围
\(1 \leq t \leq 10^{4}\)
\(1 \leq a,b \leq 10^{9}\)
题解
操作最多是2只需要判断奇偶即可,最多通过一次操作改变奇偶,再补上差值
Code
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int a,b;
cin>>a>>b;
int ans=1;
if(a==b){
cout<<"0"<<endl;
continue;
}
if(a>b){
int x=a-b;
if(x%2){
ans++;
}
}
else{
int x=b-a;
if(!(x%2)){
ans++;
}
}
cout<<ans<<endl;
}
}
B. WeirdSort
题意
给定两个数组\(a\)和\(p\),\(a\)中是无序的,只能通过交换\(p\)数组中所有的数字和他后面一项来改变顺序,问是否能达到正序
数据范围
\(1\leq t\leq 100\)
\(1\leq a_{i}\leq 100\)
\(1\leq p_{i} < n\),所有$ p_{i}$各不相同
题解
将\(p\)中的数字用unorder_map记录下来,pair记录\(a\)的下标和值,按值排序,从值最大的开始到他应该在的位置,所有数进行这样的操作,如果某一个数不可以进行就说明不能完成,因为哪一个数先移动都可以,所以只要看在原来的位置能不能移动到应该在的位置就可以
Code
cpp
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int N=110;
pii a[N];
int n,m;
void work(){
cin>>n>>m;
unordered_map<int,bool>h;
for(int i=1;i<=n;i++){
cin>>a[i].fi;
a[i].se=i;
}
for(int i=1;i<=m;i++){
int x;
cin>>x;
h[x]=1;
}
sort(a+1,a+n+1);
bool ok=1;
for(int i=n;i>=1;i--){
if(a[i].se != i ){
for(int j = a[i].se;j<i;j++){
if(!h[j]) {
ok=0;
break;
}
}
}
if(!ok) break;
}
if(ok) puts("YES");
else puts("NO");
}
int main(){
int t;
cin>>t;
while(t--){
work();
}
}
C. Perform the Combo
题意
一个字符串\(s\),长度\(n\),一个数组\(p\),长度\(m\),每个\(p[i]\)都会访问\(s[1 ~ p[i]]\),最后还会访问整个\(s\),统计26个字母每个字母被访问的次数
数据范围
\(1\leq t\leq 10^{4}\)
\(2 \leq n \leq 2 \cdot 10^{5}\)
$ 1 \leq m \leq 2 \cdot 10^{5}$
\(1 \leq p_{i}<n\)
题解
数据很大,只能允许\(O(NlogN)\)的做法,将\(p\)排序,最少的\(p\)的值一共会进行\(m+1\)次,每次都递减即可,在\(p\)中加一个\(p[m+1]=n\),每次只需要从上一个结尾后一个开始即可。
Code
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
string str;
int p[N];
int n,m;
int cnt[26];
void work(){
cin>>n>>m>>str;
for(int i=1;i<=m;i++)
cin>>p[i];
sort(p+1,p+m+1);
p[m+1]=n;
int now=m+1;
memset(cnt,0,sizeof cnt);
for(int i=1;i<=m+1;i++){
if(p[i]>p[i-1])
for(int j=p[i-1]+1;j<=p[i];j++)
cnt[str[j-1]-'a']+=now;
now--;
}
for(int i=0;i<26;i++)
cout<<cnt[i]<<' ';
cout<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
work();
}
}
D. Three Integers
题意
给定三个数字\(a,b,c\), 满足$ a \leq b \leq c $ ,每次操作可以使任意数+1或-1
求最少的操作数使得 \(a\) | \(b\) ,$ b$ | \(c\),并且始终满足\(a \leq b \leq c\)
数据范围
\(1\leq t\leq 100\)
\(1\leq a \leq b \leq c \leq 10^{4}\)
题解
从\(a\)开始暴力枚举 , \(a\)最大是\(2a\),因为\(a~2a\)中间一定存在着能被\(b\)整除的数字,最小是1,\(b\)最小和\(a\)相等最大是\(2b\),\(c\)由\(b\)推出
每次求出当前的操作数,更新答案求最小值即可
Code
cpp
#include <bits/stdc++.h>
using namespace std;
void solve(){
int a,b,c;
cin>>a>>b>>c;
int ans = INT_MAX;
int A = -1,B = -1,C = -1;
for(int nowa = 1; nowa <= 2 * a; nowa++){
for(int nowb = nowa; nowb <= 2*b; nowb += nowa){
for(int i = 0; i <= 1; i++){
int nowc = nowb * (c/nowb) + i * nowb;
int res = abs(a-nowa) + abs(b-nowb) + abs(c-nowc);
if(ans > res){
ans = res;
A = nowa;
B = nowb;
C = nowc;
}
}
}
}
cout<<ans<<endl<<A<<' '<<B<<' '<<C<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

浙公网安备 33010602011771号