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();
   }
}
posted @ 2020-05-01 13:00  Hyx'  阅读(124)  评论(0)    收藏  举报