zoukankan      html  css  js  c++  java
  • 第二周周练

    中国(北方)大学生程序射击训练赛(第二周)

    官方题解 

    A.Common Substrings

    字符串hash进行比较。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    string s1,s2;
    LL p[100005];
    int main(){
        p[0]=1;
        for(int i=1;i<100003;i++){
            p[i]=(p[i-1]*26)%mod;
        }
        int t;
        cin>>t;
        while(t--){
            cin>>s1>>s2;
            int ans=0;
            LL sum1=0,sum2=0;
            int len1=s1.size();
            int len2=s2.size();
            int len=min(len1,len2);
            for(int i=0;i<len;i++){
                LL v2=i,v1=len1-i-1;
                sum1=( sum1+(LL)(s1[v1]-'a')*p[i] )%mod;
                sum2=( sum2*26+(LL)(s2[v2]-'a') )%mod;
                if(sum1==sum2) ans++;
            }
            cout<<ans<<endl;
        }
    
        return 0;
    }
    Psong

    B.A Boring Game

    贪心。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    double a[4005];
    int n;
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            for(int i=1;i<=2*n;i++)
                scanf("%lf",&a[i]);
            int cnt=0;
            double sum=0;
            for(int i=1;i<=2*n;i++){
                if(a[i]-(int)a[i]<0.000001)
                    cnt++;
                else
                    sum+=a[i]-(int)a[i];
            }
            sum-=max(0,n-cnt);
            cnt=min(n,cnt);
            double ans=fabs(sum);
            for(int i=1;i<=cnt;i++){
                ans=min(ans,fabs(sum-i));
            }
            printf("%.3lf
    ",ans);
        }
    
        return 0;
    }
    Psong

    C.A Water Problem

    偶数考虑 i-1 和 i/2,奇数考虑 i-1 和 (i+1)/2。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <map>
    using namespace std;
    typedef long long LL;
    LL ans[10000006];
    int n,x,y;
    int main(){
        while(cin>>n>>x>>y){
            ans[1]=x;
            for(int i=2;i<=n;i++){
                if(i%2==0) ans[i]=min(ans[i-1]+x,ans[i/2]+y);
                else ans[i]=min(ans[i-1]+x,ans[i/2+1]+x+y);
            }
            cout<<ans[n]<<endl;
        }
    
        return 0;
    }
    Psong

    D.MTM

    网络流。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef pair<int,int> P;
    struct edge{
        int to,cap,cost,rev;
    };
    vector<edge> g[1000005];
    int V,n,m;
    int dis[1000005],vis[1000005];
    int prevv[1000005],preve[1000005];
    void addedge(int from,int to,int cap,int cost){
        g[from].push_back((edge){to,cap,cost,g[to].size()});
        g[to].push_back((edge){from,0,-cost,g[from].size()-1});
    }
    void SPFA(int s,int t){
        fill(dis,dis+V,inf);
        fill(vis,vis+V,0);
        dis[s]=0; vis[s]=1;
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int v=q.front();
            q.pop();
            vis[v]=0;
            for(int i=0;i<g[v].size();i++){
                edge &e=g[v][i];
                if(e.cap>0&&dis[e.to]>dis[v]+e.cost){
                    dis[e.to]=dis[v]+e.cost;
                    prevv[e.to]=v;
                    preve[e.to]=i;
                    vis[e.to]=1;
                    q.push(e.to);
                }
            }
        }
    }
    int min_cost_flow(int s,int t,int f){
        int res=0;
        while(f>0){
            SPFA(s,t);
            if(dis[t]==inf) return -1;
            int d=f;
            for(int v=t;v!=s;v=prevv[v]){
                d=min(d,g[prevv[v]][preve[v]].cap);
            }
            f-=d;
            res+=d*dis[t];
            for(int v=t;v!=s;v=prevv[v]){
                edge &e=g[prevv[v]][preve[v]];
                e.cap-=d;
                g[v][e.rev].cap+=d;
            }
        }
        return res;
    }
    int a[1005],b[1005];
    int p,q;
    void solve(int u){
        vector<int> v;
        for(int i=0;i<g[u].size();i++){
            if(g[u][i].cap)
                v.push_back(g[u][i].to);
        }
        sort(v.begin(),v.end());
        for(int i=0;i<v.size();i++){
            printf("%d",v[i]);
            if(i==v.size()-1) printf("
    ");
            else printf(" ");
        }
    }
    int main(){
        while(~scanf("%d%d%d",&n,&p,&q)){
            V=n+4;
            for(int i=0;i<V;i++)
                g[i].clear();
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            for(int i=1;i<=n;i++)
                scanf("%d",&b[i]);
            for(int i=1;i<=n;i++){
                addedge(0,i,1,0);
                addedge(i,n+1,1,-a[i]);
                addedge(i,n+2,1,-b[i]);
            }
            addedge(n+1,n+3,p,0);
            addedge(n+2,n+3,q,0);
            int ans=-min_cost_flow(0,n+3,p+q);
            printf("%d
    ",ans);
            solve(n+1);
            solve(n+2);
        }
    
        return 0;
    }
    Psong

    E.shandawang

    F.Problen of No Name

    先把边排序,按顺序用并查集合并,注意两边的大小是否大于t。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N=250005;
    struct node{
        int from,to,val;
    } g[4*N];
    bool cmp(node x,node y){
        return x.val<y.val;
    }
    int cnt;
    int f[N];
    int sz[N];
    int ans[N];
    int n,m,t,V;
    void addedge(int u,int v,int val){
        g[cnt++]=(node){u,v,val};
    }
    void init(){
        V=n*m; cnt=0;
        for(int i=1;i<=V;i++){
            f[i]=i;
            sz[i]=1;
            ans[i]=0;
        }
    }
    int getid(int x,int y){
        return (x-1)*m+y;
    }
    int find(int x){
        return f[x]==x?x:f[x]=find(f[x]);
    }
    void merge(int x,int y,int val){
        int fx=find(x);
        int fy=find(y);
        if(fx==fy) return;
        if(sz[fx]<sz[fy]) swap(fx,fy);
        if(sz[fx]<t&&sz[fy]<t){
            ans[fy]=val;
            sz[fy]+=sz[fx];
            f[fx]=fy;
        }
        if(sz[fx]>=t&&sz[fy]<t){
            ans[fy]=val;
            sz[fy]=t;
        }
    }
    int a[505][505];
    int fx[]={1,0};
    int fy[]={0,1};
    int main(){
        while(~scanf("%d%d%d",&n,&m,&t)){
            init();
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                for(int k=0;k<2;k++){
                    int xx=i+fx[k];
                    int yy=j+fy[k];
                    if(xx>n||yy>m)
                        continue;
                    addedge(getid(i,j),getid(xx,yy),
                            abs(a[xx][yy]-a[i][j]));
                }
            }
            sort(g,g+cnt,cmp);
            for(int i=0;i<cnt;i++){
                if(find(g[i].from)==find(g[i].to)) continue;
                merge(g[i].from,g[i].to,g[i].val);
            }
            long long sum=0;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                int xx; cin>>xx;
                if(xx==1)
                    sum+=ans[find(getid(i,j))];
            }
            cout<<sum<<endl;
        }
    
        return 0;
    }
    Psong

    G.Connected Components

    素数筛,并查集合并有相同素因子的元素

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long LL;
    int f[1000010];
    int find(int x){
        return f[x]==x?x:f[x]=find(f[x]);
    }
    void merge(int x,int y){
        int fx=find(x);
        int fy=find(y);
        f[fx]=fy;
    }
    vector<int> p;
    int vis[1000010];
    void init(){
        for(int i=2;i<=1000006;i++){
            if(!vis[i]){
                p.push_back(i);
                LL k=(LL)i*i;
                while(k<=1000006){
                    vis[k]=1;
                    k+=i;
                }
            }
        }
    }
    int n;
    void solve(int x){
        vector<int> g;
        for(int i=0;p[i]*p[i]<=x;i++){
            if(x%p[i]==0){
                g.push_back(p[i]);
                vis[p[i]]=1;
                while(x%p[i]==0) x/=p[i];
            }
        }
        if(x>1) g.push_back(x),vis[x]=1;;
        for(int i=1;i<g.size();i++){
            merge(g[0],g[i]);
        }
    }
    int k[1000010];
    int main(){
        init();
        int t;
        scanf("%d",&t);
        int T=t;
        while(t--){
            memset(vis,0,sizeof(vis));
            memset(k,0,sizeof(k));
            for(int i=1;i<=1000006;i++) f[i]=i;
    
            int ans=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                int a;
                scanf("%d",&a);
                if(a==1){
                    ans++;
                    continue;
                }
                solve(a);
            }
    
            for(int i=0;i<p.size();i++){
                if(vis[p[i]]){
                    if(!k[find(p[i])]){
                        k[find(p[i])]=1;
                        ans++;
                    }
                }
            }
            printf("Case %d: %d
    ",T-t,ans);
        }
    
        return 0;
    }
    Psong
  • 相关阅读:
    stress-Linux系统压力测试工具使用及系统负载很高的几种场景测试
    execsnoop-短时进程追踪工具
    走迷宫--DFS
    马踏棋盘--dfs
    查询前缀出现的次数----字典树
    找两个质数和为偶数的两个数
    煤气灶---递归
    求合力
    hdu2089---不要62(数位DP)
    轻重匹配
  • 原文地址:https://www.cnblogs.com/N-Psong/p/6558237.html
Copyright © 2011-2022 走看看