zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)_组队训练

    2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

    B Buildings

    C Joyride

    D Pants On Fire 

    F Plug It In!

    G Water Testing

    I Überwatch 

    K You Are Fired!

    B Buildings

    题意:给你m面墙,每面墙有n*n个格子,给你c种颜色,求有多种涂色方法(注意房子是一个正多边形,即旋转之后不能一样)

    题解:polya计数裸题,

    #include<bits/stdc++.h>
    #define ll long long int
    using namespace std;
    const int mod = 1e9+7;
    ll qpow(ll n,ll m)
    {
        ll res=1;
        ll k=n;
        while(m)
        {
            if(m&1)res=res*k%mod;
            k=k*k%mod;
            m/=2;
        }
        return res;
    }
    int main()
    {
        int n,m,c;
        cin>>n>>m>>c;
        ll sum = 0;
        ll g=qpow(c,n*n);
        for(int i=1;i<=m;i++)
        {
            sum+=(qpow(g,__gcd(i,m))%mod);
            sum = sum%mod;
        }
        sum=sum*qpow(m,mod-2)%mod;
        cout<<sum%mod<<endl;
    }

    C Joyride

    题意:你在游乐园玩耍,你从1出发在x分钟内你要回到1,这中间有n个娱乐设施,m条人行道,你走人行道的时间要t分钟,m行输入两点之间的人行横道,n个游乐

    设施所要花费的时间和价格,问你在x分钟内你可以花的最小钱为多少,x分钟都要用满,游乐设施可以多次玩耍。

    题解:按花费钱的数量跑最短路,dist[v][k]dist[v][k] 表示在 kk 时刻走到点 vv 最少花费 dist[v][t]dist[v][t] 元。最短路变形,用队列来优化。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1010;
    int x;
    int n,m,w;
    int t[maxn],p[maxn];
    
    struct Edge{
        int u,v,w;
        Edge(){}
        Edge(int _u,int _v){u=_u, v=_v;}
    };
    vector<Edge> E;
    vector<int> G[maxn];
    void addedge(int u,int v)
    {
        E.push_back(Edge(u,v));
        G[u].push_back(E.size()-1);
    }
    
    struct Qnode
    {
        int v,k,d;
        Qnode(){}
        Qnode(int _v,int _k,int _d) {
            v=_v, k=_k, d=_d;
        }
        bool operator<(const Qnode& oth)const {
            return d>oth.d;
        }
    };
    int dist[maxn][maxn];
    bool vis[maxn][maxn];
    void dijkstra()
    {
        memset(dist,0x3f,sizeof(dist));
        memset(vis,0,sizeof(vis));
    
        priority_queue<Qnode> Q;
        if(t[1]<=x) dist[1][t[1]]=p[1];
        else return;
        Q.push(Qnode(1,t[1],p[1]));
        while(!Q.empty())
        {
            int u=Q.top().v, k=Q.top().k; Q.pop();
            if(vis[u][k]) continue;
            vis[u][k]=1;
            if(k+t[u]<=x && dist[u][k+t[u]]>dist[u][k]+p[u])
            {
                dist[u][k+t[u]]=dist[u][k]+p[u];
                Q.push(Qnode(u,k+t[u],dist[u][k+t[u]]));
            }
            for(int i=0;i<G[u].size();i++)
            {
                Edge &e=E[G[u][i]]; int v=e.v;
                if(k+w+t[v]>x) continue;
                if(!vis[v][k+w+t[v]] && dist[v][k+w+t[v]]>dist[u][k]+p[v])
                {
                    dist[v][k+w+t[v]]=dist[u][k]+p[v];
                    Q.push(Qnode(v,k+w+t[v],dist[v][k+w+t[v]]));
                }
            }
        }
    }
    
    int main()
    {
        cin>>x>>n>>m>>w;
        for(int i=1,u,v;i<=m;i++)
        {
            cin>>u>>v;
            addedge(u,v);
            addedge(v,u);
        }
        for(int i=1;i<=n;i++) cin>>t[i]>>p[i];
        dijkstra();
        if(vis[1][x]) cout<<dist[1][x]<<endl;
        else cout<<"It is a trap."<<endl;
    }

    D Pants On Fire

    题意:给你n条定理,输入格式确定,求m条问题的正确性。

    题解:传递闭包。

    #include<bits/stdc++.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #define ll long long int
    #define mem(a,b) memset(a,b,sizeof a)
    using namespace std;
    const int INF = 0x3f3f3f3f;
    map<string,int>mp;
    int mm[404][404];
    int n,m;
    int ans;
    void Floyd()
    {
        for(int k=1;k<=ans;k++)
        {
            for(int i=1;i<=ans;i++)
            {
                for(int j=1;j<=ans;j++)
                {
                    mm[i][j] = min(mm[i][j],mm[i][k]+mm[k][j]);
                }
            }
        }
    }
    int main()
    {
        cin>>n>>m;
        ans = 1;
        mp.clear();
        for(int i=1;i<=2*n;i++)
        {
            for(int j=1;j<=2*n;j++)
            {
                if(i!=j) mm[i][j] = INF;
            }
        }
        for(int i=1;i<=n;i++)
        {
            string a,b,c,d,e;
            cin>>a>>b>>c>>e>>d;
            if(!mp[a])
            {
                mp[a] = ans;
                ans++;
            }
            if(!mp[d])
            {
                mp[d] = ans;
                ans++;
            }
            mm[mp[a]][mp[d]] = 1;
        }
        Floyd();
        while(m--)
        {
            string a,b,c,d,e;
            cin>>a>>b>>c>>e>>d;
            if(mp[a]==0||mp[d]==0)
            {
                puts("Pants on Fire");
                continue;
            }
            if(mm[mp[a]][mp[d]]==INF&&mm[mp[d]][mp[a]]==INF)
            {
                puts("Pants on Fire");
            }
            else if(mm[mp[a]][mp[d]]!=INF&&mm[mp[d]][mp[a]]==INF)
            {
                puts("Fact");
            }
            else{
                puts("Alternative Fact");
            }
        }
    }

    F Plug It In!

    题意:n个插座,m个电器,下面k行匹配关系,一个一般的插座只能插一个电器,你可以使一个的插座插三个同一电器,求最大匹配数。

    题解:先按插座的的型号进行匈牙利匹配,然后再枚举每一个型号的插座看看能不能再插电器,即再进行匈牙利匹配,二分图匹配。

    #include<bits/stdc++.h>
    #define ll long long int
    #define mem(a,b) memset(a,b,sizeof a)
    using namespace std;
    int n,m,k;
    int girl[1600],used[1600],love[1600][1600];
    int tmp[1600];
    void init()
    {
        memset(girl,0,sizeof girl);
        memset(love,0,sizeof love);
        memset(used,0,sizeof used);
    }
    bool find(int x){
        int i,j;
        for (j=1;j<=n;j++){    
            if (love[x][j]==1 && used[j]==0)      
            {
                used[j]=1;
                if (girl[j]==0 || find(girl[j])) { 
                    girl[j]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int find2(int h)
    {
        for(int i=1;i<=n;i++)
        {
            if(used[i]||!love[h][i])continue;
            used[i]=1;
            if(tmp[i]!=h&&(tmp[i]==0||find2(tmp[i])))
            {
                tmp[i]=h;return 1;
            }
        }
        return 0;
    }
    int main()
    {
        init();
        cin>>m>>n>>k;
        for(int i=1;i<=k;i++)
        {
            int x,y;
            cin>>x>>y;
            //mp[x[i]]++;
            love[x][y] = 1;
        }
        int ans = 0;
        for(int j=1;j<=m;j++)
        {
            mem(used,0);
            if(find(j)) ans++;
        }
        //cout<<ans<<endl;
        int ma=0;
        for(int i=1;i<=m;i++)
        {
            int add=0;
            for(int j=1;j<=n;j++)tmp[j]=girl[j];
            memset(used,0,sizeof(used));
            if(find2(i)){
                add++;
                memset(used,0,sizeof(used));
                if(find2(i))
                {
                        add++;
                }
            }
            ma=max(ma,add);
        }
        //cout<<ma<<" "<<ans<<endl; 
        printf("%d
    ",ma+ans);
     } 

     G Water Testing

    题意:按顺序给出边界的点,看看在封闭的图形内有多少个整数点。

    题解: 皮克定理裸体,S=a+b/21,S表示多边形的面积 a表示多边形内的整数点 b表示多边形边界上的整数点。

    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include<bitset>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<list>
    #include<deque>
    #include<map>
    #include<queue>
    #define ll long long
    #define MOD 1000000007
    #define pdd pair<double,double>
    #define mem(a,x) memset(a,x,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0)
    using namespace std;
    const long long INF = 1e18+5;
    const int inf = 0x3f3f3f3f;  
    const double eps=1e-6;       
    const int maxn=200005;    
    const double pi=acos(-1);   
    inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
    inline void read(int &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();}
    ll gcd(ll a,ll b)
    {
        if(b == 0)
            return a;
        return gcd(b,a%b);
    }
    
    ll x[maxn],y[maxn];
    int n;
    int main()
    {
        int n;
        cin >> n;
        ll x0,y0,x1,y1,S = 0;
        cin >> x[1] >> y[1];
        x0 = x[1];
        y0 = y[1];
        x1 = x[1];
        y1 = y[1];
        for(int i=2;i<=n;i++) {
            cin >> x[i] >> y[i];
            S += (x1*y[i]-y1*x[i]);
            x1 = x[i];
            y1 = y[i];
        }
        S += (x1*y0-y1*x0);
        ll sum = 0;
       // cout<<S<<endl;
        for(int i=1;i<=n;i++){
           if(i<n){
            ll aa=abs(x[i+1]-x[i]);
            ll bb=abs(y[i+1]-y[i]);
            sum+=gcd(aa,bb)-1;
           }else{
            ll aa=abs(x[1]-x[n]);
            ll bb=abs(y[1]-y[n]);
            sum+=gcd(aa,bb)-1;
           }
        }
        sum+=n;
        printf("%lld
    ",abs(S)/2+1-sum/2);
    }

    I Überwatch

    签到题:

    #include<bits/stdc++.h>
    #define ll long long int
    using namespace std;
    int x[300030];
    int dp[300030];
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>x[i];
        }
        for(int i=1;i<=n;i++)
        {
            dp[i] = dp[i-1];
            if(i>=m+1)
            {
                dp[i] = max(dp[i-m]+x[i],dp[i]);
            }
        }
        int maxx = 0;
        for(int i=1;i<=n;i++)
        {
            maxx = max(maxx,dp[i]);
        }
        cout<<maxx<<endl;
    }

    K:

    签到题

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    map<string,ll>mp;
    typedef pair<string, ll> PAIR;
    bool cmp(const PAIR &left,const PAIR &right)
    {
        return left.second > right.second;
    }
    int main()
    {
        ll n,d,k;
        cin>>n>>d>>k;
        ll ans = 0;
        for(int i=1;i<=n;i++)
        {
            string s;
            ll x;
            cin>>s>>x;
            mp[s] = x;
        }
        vector<PAIR> vec(mp.begin(),mp.end());
        sort(vec.begin(),vec.end(),cmp);
        for (vector<PAIR>::iterator it = vec.begin(); it != vec.end(); ++it)
        {
            if(d<=0) break;
            else{
                d-=it->second;
                ans++;
            }                 
        }
        if(ans>k||(ans==n&&d>0))
        {
            puts("impossible");
        }
        else{
            cout<<ans<<endl;
            ll q = 0;
            for (vector<PAIR>::iterator it = vec.begin(); it != vec.end(); ++it)
            {
                if(q>=ans) break;
                else{
                    cout<<it->first<<", YOU ARE FIRED!"<<endl;
                    q++;
                 }                 
            }
        }
    }
  • 相关阅读:
    SpringBoot中mybatis配置自动转换驼峰标识没有生效
    spring boot 配置动态刷新
    读书笔记——spring cloud 中 HystrixCommand的四种执行方式简述
    spring cloud 加入配置中心后的 部分 配置文件优先级
    spring boot 服务 正确关闭方式
    CentOS 6.4 安装 rabbitmq(3.6.15)
    CentOS 6.4 配置DNS
    CentOS 查看系统版本号
    服务治理的技术点
    【转载】C#中使用Average方法对List集合中相应元素求平均值
  • 原文地址:https://www.cnblogs.com/lcsdsg/p/14351910.html
Copyright © 2011-2022 走看看