Try Again

The German Collegiate Programming Contest 2017

B - Building

给一个m各面的多边形柱体,每一侧面有n*n个格子,现在对这些格子染色,看有多少种方式使得多面柱体无论如何旋转都不会与另一个一样。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 1000000007
ll n,m,c;
ll quickly_pow(ll x,ll y){
    ll ans=1;
    while(y){
        if(y&1) ans=ans*x%mod;
        y>>=1;
        x=x*x%mod;
    }
    return ans%mod;
}
int main(){
    scanf("%lld%lld%lld",&n,&m,&c);
    ll pos=quickly_pow(c,n*n);
    ll ans=0;
    for(ll i=1;i<=m;i++){
        ans+=quickly_pow(pos,__gcd(i,m));
        ans%=mod;
    }
    printf("%lld\n",ans*quickly_pow(m,mod-2)%mod);
    return 0;
}
View Code

 

C - Joyride

有m条边n个点,经过每个点耗时t,花费p,经过每一条边花费ti,现在问你总共时间x,确保花完,在回到出口,花费最小。

bfs+剪枝

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
vector<int>v[1006];
vector<pair<int,int> >cost(1005);
struct node{
    int u,t,w;
    node(int u,int t,int w):u(u),t(t),w(w){}
    bool operator<(const node &a) const{
        return w>a.w;
    }
};
int x,n,m,t;
int dis[1006][1006];
void bfs(){
    memset(dis,INF,sizeof(dis));
    if(x-cost[1].first<0) return ;
    priority_queue<node>q;
    dis[1][x-cost[1].first]=cost[1].second;
    q.push(node(1,x-cost[1].first,cost[1].second));
    while(!q.empty()){
        node e=q.top();
        q.pop();
        if(e.w>dis[e.u][e.t]) continue;
        if(e.t-cost[e.u].first>=0){
            if(dis[e.u][e.t-cost[e.u].first]>(dis[e.u][e.t]+cost[e.u].second)){
                dis[e.u][e.t-cost[e.u].first]=dis[e.u][e.t]+cost[e.u].second;
                q.push(node(e.u,e.t-cost[e.u].first,dis[e.u][e.t-cost[e.u].first]));
            }
        }
        for(int i=0;i<v[e.u].size();i++){
            if(e.t-t-cost[v[e.u][i]].first>=0){
                if(dis[v[e.u][i]][e.t-cost[v[e.u][i]].first-t]>(dis[e.u][e.t]+cost[v[e.u][i]].second)){
                    dis[v[e.u][i]][e.t-cost[v[e.u][i]].first-t]=dis[e.u][e.t]+cost[v[e.u][i]].second;
                    q.push(node(v[e.u][i],e.t-cost[v[e.u][i]].first-t,dis[v[e.u][i]][e.t-cost[v[e.u][i]].first-t]));
                }
            }
        }
    }
}
int main(){
    scanf("%d%d%d%d",&x,&n,&m,&t);
    for(int i=0;i<m;i++){
        int u,to;
        scanf("%d%d",&u,&to);
        v[u].push_back(to);
        v[to].push_back(u);
    }
    for(int i=1;i<=n;i++)
        scanf("%d%d",&cost[i].first,&cost[i].second);
    bfs();
    if(dis[1][0]==INF) printf("It is a trap.\n");
    else printf("%d\n",dis[1][0]);
    return 0;
}
View Code

 

D - Pants On Fire

根据前面n条句子,判断后面句子是否正确,传递性。

离散化+flyod

#include <bits/stdc++.h>
using namespace std;
map<string,int>m;
int n,q,ans=0;
int vis[406][406];
string u,v,s;
int main(){
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++){
        cin>>u>>s>>s>>s>>v;
        vis[m[u]?m[u]:(m[u]=++ans)][m[v]?m[v]:(m[v]=++ans)]=1;
    }
    for(int k=1;k<=ans;k++)
        for(int i=1;i<=ans;i++)
            for(int j=1;j<=ans;j++)
                if(vis[i][k] && vis[k][j]) vis[i][j]=1;
    while(q--){
        cin>>u>>s>>s>>s>>v;
        if(vis[m[u]][m[v]]) printf("Fact\n");
        else if(vis[m[v]][m[u]]) printf("Alternative Fact\n");
        else printf("Pants on Fire\n");
    }
    return 0;
}
View Code

 

G - Water Testing

皮克定理,求多边形内部点的数量

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Point{
  ll x,y;
}p[100005];
ll n;
ll operator * (Point a,Point b){return a.x*b.y-a.y*b.x;}
ll cal(Point a,Point b){
    if(a.x==b.x) return abs(b.y-a.y)-1;
    if(a.y==b.y) return abs(b.x-a.x)-1;
    return __gcd(abs(b.y-a.y),abs(a.x-b.x))-1;
}
ll area(){
    ll s=0;
    for(int i=0;i<n;i++)
        s+=p[i]*p[(i+1)%n];
    return abs(s);
}
ll solve(){
    ll ans=n;
    for(int i=0;i<n;i++)
        ans+=cal(p[i],p[(i+1)%n]);
    return ans-2;
}
int main(){
    scanf("%lld",&n);
    for(int i=0;i<n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y);
    printf("%lld\n",(area()-solve())/2);
    return 0;
}
View Code

 

I - Uberwatch

K - You Are Fired!

在开除不超过k个人的情况下,使得工资大于等于d

优先队列

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int AX = 1e4 + 666 ;
struct Node{
    string s ; 
    ll v ; 
    bool operator < (const Node &ch )const{
        return v < ch.v ; 
    }
}a[AX];
int main(){
    ll n,d,k;
    priority_queue<Node>q;
    scanf("%lld%lld%lld",&n,&d,&k);
    for(int i=0;i<n;i++){
        string s;
        ll c;
        cin>>s>>c;
        q.push((Node){s,c});
    }
    int ans=0;
    while(!q.empty() && d>0 && ans<k){
        Node e=q.top();
        q.pop();
        a[ans++]=e;
        //printf("%lld\n",e.v);
        d-=e.v;
    }
    if(d>0) printf("impossible\n");
    else{
        printf("%d\n",ans);
        for(int i=0;i<ans;i++){
            cout<<a[i].s<<",";
            cout<<" YOU ARE FIRED!"<<endl;
        }
    }
    return 0 ; 
}
View Code
posted @ 2018-10-27 16:52  十年换你一句好久不见  阅读(357)  评论(0编辑  收藏  举报