CF1385A~E

A.TPM

给出三个元素x,y,z,x表示max(a,b),y表示max(a,c),z表示max(b,c),请输出xyz。

推导后发现较大的两个元素必须一样,否则无解,然后输出两遍较小的元素,一遍较大的元素即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1100;
int a[3];
int main () {
    int t;
    scanf("%d",&t);
    while (t--) {
        scanf("%d%d%d",&a[0],&a[1],&a[2]);
        sort(a,a+3);
        if (a[2]==a[1]) {
            printf("YES\n");
            printf("%d %d %d\n",a[0],a[0],a[2]);
        }
        else {
            printf("NO\n");
        }
    } 
}
View Code

 

B.RPM

两个一样的排列互相插入后得到一个新序列,请你根据这个新的序列还原出原来的排列。

遍历一遍新序列,输出第一次出现的数即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
int a[maxn];
int n;
int t;
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        for (int i=1;i<=2*n;i++) scanf("%d",&a[i]);
        map<int,int> pos;
        vector<int> ans;
        for (int i=1;i<=2*n;i++) {
            if (pos[a[i]]==0) ans.push_back(a[i]),pos[a[i]]=1;
        }
        for (int i=0;i<ans.size();i++) printf("%d ",ans[i]);
        printf("\n");
    }
}
View Code

 

C.MG

给出一个序列,请你删掉它的前缀使得剩下的序列满足以下规则:

不断从开始或结束取出元素放入一个新的序列,这个序列是递增的。

用人话说就是找到这个序列最后一个峰状序列。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int a[maxn];
int t,n;
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        int ans=0;
        for (int i=n;i>=1;i--) {
            int j;
            for (j=i-1;j>=1;j--) if (a[j]<a[j+1]) break;
            int k;
            j++;
            for (k=j-1;k>=1;k--) if (a[k]>a[k+1]) break;
            ans=n-(i-k);
            break;
        }
        printf("%d\n",ans);
    }
}
View Code

 

D.GS

一个好的a-字符串的定义是:前一半是a,后一半是好的(a+1)字符串,反过来也可以。现在给出一个字符串,询问最少修改多少个字符使其变成好的字符串。

考虑一次就能修改一半,对整个字符串做DFS即可,一开始想到二分去了。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int n;
int t;
string s;
int c[26][maxn];
int Min=1e9;
void dfs (int l,int r,int wjm,int ans) {
    if (l>=r) {
        Min=min(Min,ans+r-l+1-(c[wjm][r]-c[wjm][l-1]));
        return;
    }
    int mid=(l+r)>>1;
    dfs(mid+1,r,wjm+1,ans+mid-l+1-(c[wjm][mid]-c[wjm][l-1]));
    dfs(l,mid,wjm+1,ans+r-mid-(c[wjm][r]-c[wjm][mid]));
}
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        cin>>s;
        
        for (int i=1;i<=s.length();i++) {
            for (int j=0;j<26;j++) {
                if (s[i-1]-'a'==j) 
                    c[j][i]=c[j][i-1]+1;
                else
                    c[j][i]=c[j][i-1];
            }
        }
        Min=1e9;
        dfs(1,n,0,0);
        
        /*while (l<r) {
            int mid=(l+r)>>1;
            //printf("%d %d\n",l,r);
            if (c[wjm][mid]-c[wjm][l-1]>c[wjm][r]-c[wjm][mid]) {
                ans+=mid-l+1-(c[wjm][mid]-c[wjm][l-1]);
                //printf("%d\n",ans);
                l=mid+1;
            }
            else if (c[wjm][mid]-c[wjm][l-1]<c[wjm][r]-c[wjm][mid]){
                ans+=r-mid-(c[wjm][r]-c[wjm][mid]);
                //printf("%d\n",ans);
                r=mid;
            }
            else {
                if (c[wjm+1][mid]-c[wjm+1][l-1]<=c[wjm+1][r]-c[wjm+1][mid]) {
                     ans+=mid-l+1-(c[wjm][mid]-c[wjm][l-1]);
                    //printf("%d\n",ans);
                    l=mid+1;
                } 
                else {
                    ans+=r-mid-(c[wjm][r]-c[wjm][mid]);
                    //printf("%d\n",ans);
                    r=mid;
                }
            } 
            wjm++;
        } */
        printf("%d\n",Min);
    }
}
View Code

 

E.DE

给出一个图,里面有些边是确定方向的,有些边是不确定方向的,询问是否可以把不确定方向的边确定方向,使得最终的图是有向无环图。

先假定所有无向边不存在,做拓扑排序,如果本来就有环那一定无解。然后每个节点会得到一个拓扑序,对于每条不确定的边,由拓扑序小的节点连向拓扑序大的节点。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
vector<int> g[maxn];
int inDegree[maxn];
int visit[maxn];
struct node {
    int u,v;
}edge[maxn];
int n,m;
vector<int> wjm;
int pos[maxn];
bool topo () {
    queue<int> q;
    for (int i=1;i<=n;i++) if (!inDegree[i])  {
        q.push(i),visit[i]=1;
        //break;
    }
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        wjm.push_back(u);
        for (int i=0;i<g[u].size();i++) {
            int v=g[u][i];
            if (--inDegree[v]==0) q.push(v);
        }
    }
    if (wjm.size()==n) return true;
    else return false;
}
int main () {
    int t;
    scanf("%d",&t);
    while (t--) {
        wjm.clear();
        memset(inDegree,0,sizeof(inDegree));
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) g[i].clear();
        int tot=0;
        for (int i=1;i<=m;i++) {
            int f,u,v;
            scanf("%d%d%d",&f,&u,&v);
            if (f==0) {
                edge[++tot].u=u;
                edge[tot].v=v;
                continue;
            }
            g[u].push_back(v);
            inDegree[v]++;
        }
        bool ff=topo();
        if (ff==false) {
            printf("NO\n");
            continue;
        }
        printf("YES\n");
        for (int i=0;i<wjm.size();i++) pos[wjm[i]]=i;
        for (int i=1;i<=n;i++) {
            for (int j=0;j<g[i].size();j++) printf("%d %d\n",i,g[i][j]);
        }
        for (int i=1;i<=tot;i++) {
            int u=edge[i].u;
            int v=edge[i].v;
            if (pos[u]>pos[v]) swap(u,v);
            printf("%d %d\n",u,v);
        }
    }
}
View Code

 

posted @ 2020-07-18 15:02  zlc0405  阅读(184)  评论(0编辑  收藏  举报