CF1144A~G

1144A.DS

给出一个字符串,只可能包含小写字母,要求不能有重复的字符和里面的字母是一串连续的数字(bcdef...),输出Yes或No。

对字符串排序即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int t;
string s;
int main () {
    cin>>t;
    while (t--) {
        cin>>s;
        if (s.length()==1) {
            printf("Yes
");
            continue;
        }
        if (s.length()>26) {
            printf("No
");
            continue;
        }
        set<int> st;
        for (int i=0;i<s.length();i++) st.insert(s[i]);
        if (st.size()!=s.length()) {
            printf("No
");
            continue;
        }
        sort(s.begin(),s.end());
        int f=1;
        for (int i=0;i<s.length()-1;i++)
            if (s[i+1]-s[i]>1) f=0;
        if (f)
            printf("Yes
");
        else
            printf("No
");
    }
}
View Code

1144B.PAD

对一个序列做删除操作,每次删除元素的奇偶性必须与上次删除的元素的奇偶性相反,当找不到奇偶性相反的元素的时候就停止删除,询问序列中剩下元素的最大值。

开两个数组分别存储序列中的奇数和偶数,然后从大到小排序,分别判断奇数多和偶数多两种情况,具体看代码。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2005;
typedef long long ll;
int n;
int a[maxn];
int main () {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    vector<int> v[2]; 
    for (int i=1;i<=n;i++) {
        v[a[i]%2].push_back(a[i]);
    }
    sort(v[0].begin(),v[0].end());
    sort(v[1].begin(),v[1].end());
    if (v[0].size()==v[1].size()) {
        printf("0
");
        return 0;
    }
    if (v[0].size()>v[1].size()) {
        ll ans=0;
        for (int i=0;i<v[0].size()-v[1].size()-1;i++) ans+=v[0][i];
        printf("%lld
",ans);
        return 0;
    }
    else {
        ll ans=0;
        for (int i=0;i<v[1].size()-v[0].size()-1;i++) ans+=v[1][i];
        printf("%lld
",ans);
        return 0;
    }
}
View Code

1144C.TSC

给出一个序列,里面的数字可以打乱顺序,请你组出两个序列,分别严格递增和递减,或者输出不可能。

显然当有一个数字出现次数大于2是无解的。

然后开一个哈希表存储数字,分别正向反向遍历表,枚举出答案。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int a[maxn];
int cnt[maxn];
int n;
int main () {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++;
    for (int i=0;i<maxn;i++) if (cnt[i]>2) {
        printf("NO
");
        return 0;
    }
    vector<int> v1,v2;
    for (int i=0;i<maxn;i++) {
        if (cnt[i]>0) {
            v1.push_back(i);
            cnt[i]--;
        }
    }
    for (int i=maxn-1;i>=0;i--) {
        if (cnt[i]>0) {
            v2.push_back(i);
            cnt[i]--;
        }
    }
    printf("YES
");
    printf("%d
",v1.size());
    for (int i=0;i<v1.size();i++) printf("%d ",v1[i]);
    printf("
");
    printf("%d
",v2.size());
    for (int i=0;i<v2.size();i++) printf("%d ",v2[i]);
    printf("
");
}
View Code

1144D.ETA

有两种操作,一种是使后面的数和前面的数一样,一种是使前面的数和后面的数一样,询问最少操作数使得整个数组的每个元素相等。

显然使得每个数和出现最多的数字相等操作次数最少。

先枚举出出现次数最多的那个数,然后随便找一个这个数出现的位置,分别向左边和右边做两种操作。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int n;
int a[maxn];
map<int,int> cnt;
struct node {
    int op,i,j;
};
int main () {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++;
    int wjm=-1,Max=0;
    for (auto it=cnt.begin();it!=cnt.end();it++)
        if (it->second>Max) Max=it->second,wjm=it->first;
    vector<node> v;
    int pre=1;
    for (int i=1;i<=n;i++) {
        if (a[i]==wjm) {
            int j;
            for (j=i-1;j>=1;j--) {
                if (a[j]<wjm)
                    v.push_back({1,j,j+1});
                else if (a[j]>wjm)
                    v.push_back({2,j,j+1});
            }
            for (j=i+1;j<=n;j++) {
                if (a[j]<wjm)
                    v.push_back({1,j,j-1});
                else if (a[j]>wjm)
                    v.push_back({2,j,j-1});    
            }
            break;
        }
    }
    
    printf("%d
",v.size());
    for (int i=0;i<v.size();i++) printf("%d %d %d
",v[i].op,v[i].i,v[i].j);
} 
View Code

1144E.MS

给出两个序列s和t,找到他们的字典序的中位数对应的序列。

模拟26进制的相加和除法。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int n;
char s[maxn];
char t[maxn];
int wjm[maxn];
int main () {
    scanf("%d",&n);
    scanf("%s",s);
    scanf("%s",t);
    for (int i=n-1;i>=0;i--) {
        int x=t[i]-'a';
        int y=s[i]-'a';
        if (x-y<0) {
            //借位
            t[i-1]--;
            x+=26; 
        }
        if ((x-y)%2==0) wjm[i]=(x-y)/2;
        else {
            wjm[i]=(x-y)/2;
            wjm[i+1]+=13;
        }
    }
    for (int i=n-1;i>=0;i--) {
        int x=s[i]-'a';
        wjm[i-1]+=(x+wjm[i])/26;
        wjm[i]=(x+wjm[i])%26;
    }
    for (int i=0;i<n;i++) printf("%c",wjm[i]+'a');
    
}
View Code

1144F.GWLDP

给出一个无向图,请你把里面的边改成有向的,使得答案有向图不存在大于等于2的路径。

二分图染色一遍就可以。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
struct node {
    int u,v;
}edge[maxn];
vector<int> g[maxn];
int n,m;
int c[maxn];
int wjm;
void dfs (int u) {
    for (int v:g[u]) {
        if (!c[v])  {
            c[v]=3-c[u];
            dfs(v);
        }
        else if (c[u]==c[v]) {
            wjm=0;
        }
    }
}
int main () {
    scanf("%d%d",&n,&m);
    wjm=1;
    for (int i=1;i<=m;i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
        edge[i].u=x;
        edge[i].v=y;
    }
    c[1]=1;
    dfs(1);
    if (!wjm) {
        printf("NO
");
        return 0;
    }
    printf("YES
");
    for (int i=1;i<=m;i++) {
        if (c[edge[i].u]==1)
            printf("1");
        else
            printf("0");
    }
}
View Code

1144G.TMS

给出一个序列,请你把它分成两份,一份是严格递增的,一份是严格递减的。

贪心,维护当前递增序列的最后一个元素和递减序列的最后一个元素,然后判断当前元素能加入哪个序列。

如果都可以,就取出后面那个元素,比较当前元素和后面那个元素的大小。思想是使得后面元素的选择空间更大。

//贪心
//维护当前下降序列的最后一个元素和上升序列的最后一个元素
//a[i]>Min&&a[i]<Max无解
//a[i]<Min&&a[i]<Max进入下降序列
//a[i]>Min&&a[i]>Max进入上升序列
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int a[maxn];
int wjm[maxn];
int n;
int main () {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    int Min=1e9,Max=-1e9;
    int f=1;
    for (int i=1;i<=n;i++) {
        if (a[i]>=Min&&a[i]<=Max) {
            f=0;break;
        }
        if (a[i]<Min&&a[i]<=Max) {
            wjm[i]=1;
            Min=a[i];
            continue;
        } 
        if (a[i]>=Min&&a[i]>Max) {
            wjm[i]=0;
            Max=a[i];
            continue;
        }
        if (a[i]<Min&&a[i]>Max) {
            if (a[i]>a[i+1])
                wjm[i]=1,Min=a[i];
            else
                wjm[i]=0,Max=a[i];
            continue;
        }
    }
    if (!f) {
        printf("NO
");
        return 0;
    }
    printf("YES
");
    for (int i=1;i<=n;i++) printf("%d ",wjm[i]);
    
} 
View Code
原文地址:https://www.cnblogs.com/zhanglichen/p/13323485.html