• 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
    ");
                printf("%d %d %d
    ",a[0],a[0],a[2]);
            }
            else {
                printf("NO
    ");
            }
        } 
    }
    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("
    ");
        }
    }
    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
    ",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
    ",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
    ",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
    ",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
    ",ans);
                        l=mid+1;
                    } 
                    else {
                        ans+=r-mid-(c[wjm][r]-c[wjm][mid]);
                        //printf("%d
    ",ans);
                        r=mid;
                    }
                } 
                wjm++;
            } */
            printf("%d
    ",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
    ");
                continue;
            }
            printf("YES
    ");
            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
    ",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
    ",u,v);
            }
        }
    }
    View Code
  • 相关阅读:
    【POJ 2987 Firing】 最大权闭合子图
    【sgu176】有源汇有上下界的最大/最小流
    【HDU1263 水果】 STL之map应用经典好题
    【HDU1227 Fast Food】经典DP
    【hdu1043 && poj 1077】八数码问题
    有上下界的网络流问题
    【HDU4521】 dp思想+线段树操作
    miracl库下椭圆曲线方程常用函数使用入门
    函数指针
    python数据查询操作之 一场缺少db.commit()引发的血案……
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13335812.html
Copyright © 2020-2023  润新知