GVKun编程网logo

2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?(2017安卓)

4

本文的目的是介绍2017Android和iOS频频被曝Bug,它们都怎么了?的详细情况,特别关注2017安卓的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解2017A

本文的目的是介绍2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?的详细情况,特别关注2017安卓的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?的机会,同时也不会遗漏关于(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)、2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)、2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Solution、2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) D bfs 思维 E bfs I Floyd 找最小环...的知识。

本文目录一览:

2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?(2017安卓)

2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?(2017安卓)

虽然很多采用 Android 系统的厂商还未更新 8.0 系统,但谷歌已经开始为自家支持的 Pixel 设备推送最新的 Android 8.1 了。上周,Android 8.1 系统刚刚在谷歌 Pixel 设备上推送发布。但随后用户就发现了 Android 8.1 系统存在的严重 Bug,直接影响到了他们使用手机的体验。

更新 Android 8.1 之后,就有 Pixel C 平板用户反映升级后竟然自动恢复出厂设置,所有数据都被擦除。

随后,大量用户在 Google 论坛、Reddit 论坛中反馈,称在 Android 8.1 下出现了严重的多点触控失效问题。这个问题说严重点就是,会直接影响到用户在多场景方面的操作。尤其玩游戏时,特别是 FPS 射击游戏,因为需要同时使用多根手指操作,这一 Bug 最为明显,直接导致画面出现严重的跳跃、抖动现象,无法进行游戏。

Pixel 用户社区管理员 Oririn 针对用户反馈的问题正式作出回应:“正在就此进行调查,并希望碰到 Bug 的用户及时反馈。”

联想到今年早些时候 Android 8.0 曝出的开启 WiFi 仍会使用数据、蓝牙连接错误、导致 OLED 烧屏等 Bug,以及同为难兄难弟,被曝出触摸屏失灵、摄像头无法对焦、无限重启、Face ID 启动失败、HomeKit 安全漏洞等问题的 iOS 11,不禁让一些网友吐槽:“iOS 和 Android ,2017 年都怎么了?”

(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

<a href="https://codeforces.com/gym/101933/" target="_blank"><strong>传送门</strong></a>

付队!

许老师!

B.Buildings (polya定理)

题意

B:给你m面墙,每面墙是n*n的格子,你有c种颜色,问你有多少种涂色方案。用polya定理

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
///a<mod 并且 p为素数
ll pow_mod(ll x, ll n, ll mod){
    ll res=1;
    while(n){
        if(n&1)res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
ll inv(ll a,ll p){return pow_mod(a,p-2,p);}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n,m,c;
    cin>>n>>m>>c;
    ll ans=0;
    for(int i=0;i<m;i++){
        ans+=pow_mod(c,n*n*__gcd(i,m),mod);
        ans%=mod;
    }
    cout<<ans*inv(m,mod)%mod<<endl;
    return 0;
}

C.Joyride (分层图最短路)

题意

C:游乐场有n个设施,有m条人行道,游乐设施会花费ti的时间和pi的钱,人行道需要花费t的时间,你需要用最少的钱恰好游玩x的时间,起点是1,终点是1,求最少的钱是多少4

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e3+50;
const int inf=1e9+7;
int x,n,m,t;
vector<int>ve[maxn];
struct need{
  int t,p;
}ned[maxn];
struct node{
    int in;
    int w;
    int time;
};
int dis[maxn][maxn];
void dij(){
    queue<node>q;
    q.push(node{1,ned[1].p,ned[1].t});
    for(int i=0;i<=1000;i++){
        for(int j=0;j<=1000;j++)dis[i][j]=inf;
    }
    dis[1][ned[1].t]=ned[1].p;
    while(!q.empty()){
        node now=q.front();
        q.pop();
        int in=now.in,w=now.w,time=now.time;
        if(time+ned[in].t<=x&&w+ned[in].p<dis[in][time+ned[in].t]){
            dis[in][time+ned[in].t]=w+ned[in].p;
            q.push(node{in,dis[in][time+ned[in].t],time+ned[in].t});
        }
        for(int i=0;i<ve[in].size();i++){
            int nex=ve[in][i];
            int nextime=time+t+ned[nex].t;
            if(nextime<=x&&dis[nex][nextime]>w+ned[nex].p){
                dis[nex][nextime]=w+ned[nex].p;
                q.push(node{nex,w+ned[nex].p,nextime});
            }
        }
    }
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    cin>>x>>n>>m>>t;
    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        ve[a].push_back(b);
        ve[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        cin>>ned[i].t>>ned[i].p;
    }
    dij();
    if(dis[1][x]==inf)cout<<"It is a trap."<<endl;
    else cout<<dis[1][x]<<endl;
    return 0;
}

D.Pants On Fire (map+dfs,or 传递闭包)

题意

D 有n个已知串,给m个串,让你去判断他们是对的还是错的还是未知的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e3+50;
const int inf=1e9+7;
map<string,int>mp;
int cnt;
bool ok[500][500];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    string a,b,c,d,e;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a>>b>>c>>d>>e;
        if(!mp[a])mp[a]=++cnt;
        if(!mp[e])mp[e]=++cnt;
        ok[mp[a]][mp[e]]=true;
    }
    for(int k=1;k<=cnt;k++){
        for(int i=1;i<=cnt;i++){
            for(int j=1;j<=cnt;j++){
                ok[i][j]|=ok[i][k]&&ok[k][j];
            }
        }
    }
    for(int i=1;i<=m;i++){
        cin>>a>>b>>c>>d>>e;
        if(!mp[a]||!mp[e]){cout<<"Pants on Fire"<<endl;continue;}
        int u=mp[a],v=mp[e];
        if(ok[u][v])cout<<"Fact"<<endl;
        else if(ok[v][u])cout<<"Alternative Fact"<<endl;
        else{
            cout<<"Pants on Fire"<<endl;
        }
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e3+50;
const int inf=1e9+7;
map<string,int>mp;
int cnt;
vector<int>G[maxn];
bool dfs(int u,int v){

    for(int i=0;i<G[u].size();i++){
        if(G[u][i]==v)return true;
        bool ok=dfs(G[u][i],v);
        if(ok)return true;
    }
    return false;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    string a,b,c,d,e;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a>>b>>c>>d>>e;
        if(!mp[a])mp[a]=++cnt;
        if(!mp[e])mp[e]=++cnt;
        G[mp[a]].push_back(mp[e]);
    }
    for(int i=1;i<=m;i++){
        cin>>a>>b>>c>>d>>e;
        if(!mp[a]||!mp[e]){cout<<"Pants on Fire"<<endl;continue;}
        int u=mp[a],v=mp[e];
        if(dfs(u,v))cout<<"Fact"<<endl;
        else if(dfs(v,u))cout<<"Alternative Fact"<<endl;
        else{
            cout<<"Pants on Fire"<<endl;
        }
    }
    return 0;
}

F.Plug It In (匈牙利算法/二分图匹配/网络流)

题意

m个插口,n个电器 k个可以匹配的连接 ,问你最大匹配数,但是你有一次机会把一个接口变成三个一样的

思路

考虑暴力每次暴力把一个其中一个接口数+2跑匈牙利算法,复杂度N^3,然后发现其实第一次跑的最初的图是可以一直重复利用的,然后就直接把后面的多出来的接口拿去跑增广路就行。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
/// 二分图最大基数匹配

int mp[1550][1550];
int link[1550];
int n,m,k;
bool vis[1550];
int remain[1550];
bool match(int u){
    for(int i=1;i<=m;i++){
        if(vis[i]==0&&mp[u][i]){
            vis[i]=1;
            if(link[i]==-1||match(link[i])){
                link[i]=u;
                return 1;
            }
        }
    }
    return 0;
}


int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int k;
    cin>>n>>m>>k;
    memset(link,-1,sizeof(link));
    for(int i=1;i<=k;i++){
        int a,b;
        cin>>a>>b;
        mp[a][b]=1;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(match(i))ans++;
    }
    for(int i=1;i<=m;i++){
        remain[i]=link[i];
    }
    int mx=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)mp[n+1][j]=mp[n+2][j]=mp[i][j];
        for(int i=1;i<=m;i++){
            link[i]=remain[i];
        }
        int now=0;
        memset(vis,0,sizeof(vis));
        for(int j=n+1;j<=n+2;j++){
            if(match(j))now++;
        }
        mx=max(now,mx);
    }
    cout<<ans+mx<<endl;
    return 0;
}

G.Water Testing (皮克定理)

题意

给你一个多边形问你多边形中的整点个数有多少

思路

皮克定理

皮克定理是指一个计算点阵中顶点在格点上的多边形面积公式,该公式可以表示为2S=2a+b-2,其中a表示多边形内部的点数,b表示多边形边界上的点数,S表示多边形的面积。

其中,面积用每两条线的叉积计算

image

当O点为原点时,根据向量的叉积计算公式,各个三角形的面积计算如下:

S_OAB = 0.5*(A_xB_y - A_yB_x) 【(A_x,A_y)为A点的坐标】

S_OBC = 0.5*(B_xC_y - B_yC_x)

S_OCD = 0.5*(C_xD_y - C_yD_x)

S_ODE = 0.5*(D_xE_y - D_yE_x)

S_OEA = 0.5*(E_xA_y - E_yA_x)

边界的点数用gcd(a.x-b.x,a.y-b.y)计算

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
struct Point{
    ll x,y;
}my[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>my[i].x>>my[i].y;
    }
    ll s=0,b=0;
    for(int i=0;i<n;i++){
        s+=my[i].x*my[(i+1)%n].y-my[(i+1)%n].x*my[i].y;
        b+=__gcd(abs(my[i].x-my[(i+1)%n].x),abs(my[i].y-my[(i+1)%n].y));
    }

    s/=2;
    s=abs(s);
    cout<<s-b/2+1<<endl;
    return 0;
}

I.Uberwatch (基础DP)

思路

对于每个点考虑两种情况,如果他不放必杀技那 $$ dp[i]=dp[i-1] $$ 如果他放必杀技,那么他就只能在i-m时间之前放的最大值加起来 $$ dp[i]=dp[i-m]+a[i] $$

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int a[maxn];
int dp[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int sum=0;
    for(int i=m+1;i<=n;i++){
        dp[i]=max(dp[i-1],dp[i-m]+a[i]);
    }
    cout<<dp[n]<<endl;
    return 0;
}

K.You Are Fired (签到)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
struct node{
    ll money;
    string name;

}my[maxn];
bool vis[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    ll n,d,k;
    cin>>n>>d>>k;
    for(int i=1;i<=n;i++){
        cin>>my[i].name>>my[i].money;
    }
    sort(my+1,my+1+n,[](node a,node b){
        return a.money>b.money;
    });
    ll ans=0,num=0;
    for(int i=1;i<=k;i++){
        ans+=my[i].money;
        vis[i]=true;
        num++;
        if(ans>=d)break;
    }
    if(ans<d)cout<<"impossible"<<endl;
    else{
        cout<<num<<endl;
        for(int i=1;i<=n;i++){
            if(vis[i])
            cout<<my[i].name<<", YOU ARE FIRED!"<<endl;
        }
    }
    return 0;
}

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

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

A Drawing Borders

很多构造方法,下图可能是最简单的了

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct Point{ int x,y; };
Point a[maxn];  int numa=0;
Point b[maxn];  int numb=0;
vector<pair<double,double> > va;
vector<pair<double,double> > vb;
void checka()
{
    va.push_back({3000,3000});
    va.push_back({3000,2999});
    for(int i=numa;i>=1;i--)
    {
        va.push_back( { a[i].x*1.000-0.3,2999} );
        va.push_back( { a[i].x*1.000-0.3,a[i].y*1.000+0.1} );
        va.push_back( { a[i].x*1.000+0.1,a[i].y*1.000+0.1} );
        va.push_back( { a[i].x*1.000+0.1,a[i].y*1.000-0.1} );
        va.push_back( { a[i].x*1.000-0.3,a[i].y*1.000-0.1} );
        while(i-1>=1 && a[i-1].x==a[i].x)
        {
            i--;
            va.push_back( { a[i].x*1.000-0.3,a[i].y*1.000+0.1} );
            va.push_back( { a[i].x*1.000+0.1,a[i].y*1.000+0.1} );
            va.push_back( { a[i].x*1.000+0.1,a[i].y*1.000-0.1} );
            va.push_back( { a[i].x*1.000-0.3,a[i].y*1.000-0.1} );
        }
        va.push_back( {a[i].x*1.0000-0.3,-1200} );
        va.push_back( {a[i].x*1.0000-0.39,-1200} );
        va.push_back( {a[i].x*1.0000-0.39,2999});
    }
    va.push_back({-3000,2999});
    va.push_back({-3000,3000});
}
void checkb()
{
    vb.push_back({-3000,-3000});
    vb.push_back({-3000,-2999});
    for(int i=1;i<=numb;i++)
    {
        vb.push_back( { b[i].x*1.000+0.3,-2999} );


        vb.push_back( { b[i].x*1.000+0.3,b[i].y*1.000-0.1} );
        vb.push_back( { b[i].x*1.000-0.1,b[i].y*1.000-0.1} );
        vb.push_back( { b[i].x*1.000-0.1,b[i].y*1.000+0.1} );
        vb.push_back( { b[i].x*1.000+0.3,b[i].y*1.000+0.1} );
        while(i+1<=numb && b[i+1].x==b[i].x)
        {
            i++;
            vb.push_back( { b[i].x*1.000+0.3,b[i].y*1.000-0.1} );
            vb.push_back( { b[i].x*1.000-0.1,b[i].y*1.000-0.1} );
            vb.push_back( { b[i].x*1.000-0.1,b[i].y*1.000+0.1} );
            vb.push_back( { b[i].x*1.000+0.3,b[i].y*1.000+0.1} );
        }
        vb.push_back( { b[i].x*1.000+0.3,1200} );
        vb.push_back( { b[i].x*1.000+0.39,1200} );
        vb.push_back( { b[i].x*1.000+0.39,-2999} );
    }
    vb.push_back({3000,-2999});
    vb.push_back({3000,-3000});
}
bool upa(Point a,Point b){if(a.x==b.x) return a.y<b.y;return   a.x<b.x;}
bool upb(Point a,Point b){if(a.x==b.x) return a.y<b.y;return   a.x<b.x;}
int main()
{
    int n ; scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y,z; scanf("%d %d %d",&x,&y,&z);
        if(z==1) a[++numa].x=x,a[numa].y=y;
        if(z==2) b[++numb].x=x,b[numb].y=y;
    }
    sort(a+1,a+1+numa,upa);   checka();
    sort(b+1,b+1+numb,upb);   checkb();
    printf("%d\n",va.size()); for(int i=0;i<va.size();i++) printf("%.4f %.4f\n",va[i].first,va[i].second);
    printf("%d\n",vb.size()); for(int i=0;i<vb.size();i++) printf("%.4f %.4f\n",vb[i].first,vb[i].second);
}
View Code

B Buildings

polya定理

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int quick(int a,int n)
{
    int ans=1;
    while(n)
    {
        if(n%2==0) {a=a%mod*a%mod;n=n/2; }
        else       {ans=ans%mod*a%mod;   n--;   }
    }
    return ans;
}
int p[500+10];
int32_t main()
{
   int n,m,c; cin>>n>>m>>c;//  m  temp;
   int temp=quick(c,n*n); //cout<<temp<<endl;
   p[0]=1;
   for(int i=1;i<= m;i++) p[i]=p[i-1]%mod*temp%mod;
   int a=0;
   for(int i=0;i<m;i++)  a+=p[__gcd(i,m)],a=a%mod;
   int ans=a*quick(m,mod-2)%mod;
   cout<<ans<<endl;
}
View Code

C Joyride

dp + 记忆化搜索

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head

const int N = 1e3 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
LL dp[N][N];
vector<int> g[N];
int x, n, m, T, u, v;
int t[N], p[N];
LL dfs(int u, int m) {
    if(m > x) return INF;
    if(~dp[u][m]) return dp[u][m];
    if(u == 1 && m == x) return dp[u][m] = 0;
    dp[u][m] = INF;
    for (int v : g[u]) {
        dp[u][m] = min(dp[u][m], dfs(v, m+T+t[v]) + p[v]);
    }
    dp[u][m] = min(dp[u][m], dfs(u, m+t[u])+p[u]);
    return dp[u][m];
}
int main() {
    mem(dp, -1);
    scanf("%d", &x);
    scanf("%d %d %d", &n, &m, &T);
    for (int i = 1; i <= m; ++i) scanf("%d %d", &u, &v), g[u].pb(v), g[v].pb(u);
    for (int i = 1; i <= n; ++i) scanf("%d %d", &t[i], &p[i]);
    LL tmp = dfs(1, t[1]) + p[1];
    if(t[1]*2 > x || tmp >= INF) printf("It is a trap.\n");
    else printf("%lld\n", tmp);
    return 0;
}
View Code

D Pants On Fire

拓扑排序

代码:

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

/*

⊂_ヽ
  \\ Λ_Λ  来了老弟
   \(''ㅅ'')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
''ノ )  Lノ

*/

using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ''\n''

#define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);


const ll oo = 1ll<<17;
const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<''0''||ch>''9'') f|=(ch==''-''),ch=getchar();
    while (ch>=''0''&&ch<=''9'') x=x*10+ch-''0'',ch=getchar();
    return x=f?-x:x;
}

inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;}

/*-----------------------showtime----------------------*/
            string str[10];
            map<string ,int>mp;
            vector<int>G[509];
            int fa[509],du[509],dig[509];
            int find(int x) {
                if(fa[x] == x) return x;
                return fa[x] = find(fa[x]);
            }
            int dfs(int s,int t){
                int flag = 0;
                for(int i=0; i<G[s].size(); i++){
                    int v = G[s][i];
                    if(v == t) flag = 1;
                    flag = (flag || dfs(v, t));
                }
                return flag;
            }
int main(){
            int n,m;
            scanf("%d%d", &n, &m);
            int tot = 0;
            rep(i, 1, 508) fa[i] = i;
            rep(i, 1, n) {
                rep(j, 1, 5) cin>>str[j];
                int u,v;
                if(mp.count(str[1]))  u = mp[str[1]];
                else {
                    ++tot; u = tot;
                    mp[str[1]] = tot;
                }

                if(mp.count(str[5]))  v = mp[str[5]];
                else {
                    ++tot; v = tot;
                    mp[str[5]] = tot;
                }

                int fx = find(u), fy = find(v);
                fa[fx]=  fy;
                G[u].pb(v);
            }


            for(int i=1; i<=m; i++){
                 rep(j, 1, 5) cin>>str[j];
                 if(mp.count(str[1]) == 0 || mp.count(str[5]) == 0) {
                    puts("Pants on Fire");
                    continue;
                 }
                 int u = mp[str[1]];
                 int v = mp[str[5]];
                 if(find(u) != find(v) ) puts("Pants on Fire");
                 else if(dfs(u, v)) puts("Fact");
                 else if(dfs(v, u))puts("Alternative Fact");
                 else puts("Pants on Fire");
            }
            return 0;
}
View Code

E Perpetuum Mobile

spfa判正权环

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head

const int N = 800 + 10;
double d[N];
struct edge {
    int to;
    double w;
};
vector<edge> g[N];
bool vis[N];
bool spfa(int u) {
    vis[u] = true;
    for (edge v : g[u]) {
        if(d[u] + v.w < d[v.to]) {
            d[v.to] = d[u] + v.w;
            if(vis[v.to]) return true;
            if(spfa(v.to)) return true;
        }
    }
    vis[u] = false;
    return false;
}
int main() {
    int n, m, u, v;
    double w;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; ++i) {
        scanf("%d %d %lf", &u, &v, &w);
        g[u].pb({v, -log(w)});
    }
    for (int i = 1; i <= n; ++i) d[i] = 0;
    for (int i = 1; i <= n; ++i) if(spfa(i)) {
        puts("inadmissible");
        return 0;
    }
    puts("admissible");
    return 0;
}
View Code

F Plug It In

枚举三个插座的位置,拆点,然后二分图匹配

代码:

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

/*

⊂_ヽ
  \\ Λ_Λ  来了老弟
   \(''ㅅ'')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
''ノ )  Lノ

*/

using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ''\n''

#define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);


const ll oo = 1ll<<17;
const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<''0''||ch>''9'') f|=(ch==''-''),ch=getchar();
    while (ch>=''0''&&ch<=''9'') x=x*10+ch-''0'',ch=getchar();
    return x=f?-x:x;
}

inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;}

/*-----------------------showtime----------------------*/
            const int maxn = 1509;
            int pt[maxn],vis[maxn];
            struct node{
                int cnt;
                int id;
            }a[maxn];
            queue<int>que;
            vector<int>mp[maxn];
            int col = 0;
            bool dfs(int u){
                if(vis[u] == col) return false;
                vis[u] = col;
                for(int i=0; i<mp[u].size(); i++){
                    int v = mp[u][i];
                    if(pt[v] ==0 || dfs(pt[v])) {
                        pt[v] = u;
                        return true;
                    };
                }
                return false;
            }
            int in[maxn];

            bool cmp(node a,node b){
                return a.cnt < b.cnt;
            }
int main(){
            int n,m,k;
            scanf("%d%d%d", &n, &m, &k);
            rep(i, 1, m) a[i].id = i;
            for(int i=1; i<=k; i++){
                int u,v;
                scanf("%d%d", &u, &v);
                mp[v].pb(u);
                a[v].cnt++;
            }

            sort(a+1, a+1+m, cmp);
            int ans = 0;
            for(int i=1; i<=m; i++) {
                   // memset(vis, 0, sizeof(vis));
                    col++;
                    if(dfs(a[i].id) == 0) que.push(a[i].id);
                    else ans++;
            }
            int mx = 0;
            while(!que.empty()){
                int u = que.front(); que.pop();
                for(int i=0; i<mp[u].size(); i++)
                    {
                        int v = mp[u][i];
                        in[v]++;
                        mx = max(mx, in[v]);
                    }
            }
            mx = min(2, mx);
            ans += mx;
            printf("%d\n", ans);
            return 0;
}
View Code

G Water Testing

皮克定理

代码:

#include<bits/stdc++.h>
#define int long long
#define MAX(a,b,c) max(a,max(b,c))
#define MIN(a,b,c) min(a,min(b,c))
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef unsigned long long uLL;
using namespace std;
const int maxn=1e6+10;
const int mod=1e9+7;
struct Point{int x;int y;}pa[maxn];
int  Cross(Point A,Point B) { return A.x*B.y-A.y*B.x;   }  // 叉积
/*bool anglecmp(Point a, Point b)
{
    if(a.y <= 0 && b.y > 0) return true;
    if(a.y > 0 && b.y <= 0) return false;
    if(!a.y && !b.y) return a.x < b.x;
    return Cross(a,b) > 0;
}*/
int work(Point a,Point b)
{
    return __gcd( abs(a.x-b.x),abs(b.y-a.y) )-1;
}
int32_t main()
{
    int n; scanf("%lld",&n);
    for(int i=1;i<=n;i++)  scanf("%lld %lld",&pa[i].x,&pa[i].y);
    //sort(pa+1,pa+1+n,anglecmp);
    int ans=0;
    for(int i=1;i<n;i++)
    ans+=Cross(pa[i],pa[i+1]);
    ans+=Cross(pa[n],pa[1]);
    ans=abs(ans);
    int x=n;
    for(int i=1;i<n;i++)
    x+=work(pa[i],pa[i+1]);
    x+=work(pa[n],pa[1]);
    int a=(ans-x+2)/2;
    printf("%lld\n",a);
}
View Code

H Ratatoskr

枚举根,求最长链,然后取最小

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";


const int N = 85;
vector<int> g[N];
int dfs(int u, int o) {
    int res = 1;
    for (int v : g[u]) {
        if(v != o) res = max(res, dfs(v, u)+1);
    }
    return res;
}
int main() {
    int n, a, b, c, u, v;
    scanf("%d", &n);
    scanf("%d %d %d", &a, &b, &c);
    for (int i = 1; i < n; ++i) scanf("%d %d", &u, &v), g[u].pb(v), g[v].pb(u);
    int ans = n;
    for (int i = 1; i <= n; ++i) {
        if(i == b || i == c) ans =min(ans, dfs(i, i)-1);
        else ans = min(dfs(i, i), ans);
    }
    printf("%d\n", ans);
    return 0;
}
View Code

I Uberwatch

dp

代码:

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

/*

⊂_ヽ
  \\ Λ_Λ  来了老弟
   \(''ㅅ'')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
''ノ )  Lノ

*/

using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ''\n''

#define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);


const ll oo = 1ll<<17;
const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<''0''||ch>''9'') f|=(ch==''-''),ch=getchar();
    while (ch>=''0''&&ch<=''9'') x=x*10+ch-''0'',ch=getchar();
    return x=f?-x:x;
}

inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;}

/*-----------------------showtime----------------------*/
            const int maxn = 3e5+9;
            int a[maxn],dp[maxn],res[maxn];
int main(){
            int n,m;
            scanf("%d%d", &n, &m);
            rep(i, 1, n) scanf("%d", &a[i]);

            rep(i, m+1, n) {
                dp[i] = max(dp[i],res[i-m] + a[i]);
                res[i] = max(res[i-1], dp[i]);
            }
            printf("%d\n", res[n]);
            return 0;
}
View Code

J Word Clock

旅行商问题变形,状压dp实现

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const int N = 19;
const int INF = 0x3f3f3f3f;
int h, w, n;
string t[N], s[N];
int d[N][N], up;
pii dp[N][1<<N];
int pre[N][1<<N];
pii dfs(int u, int st) {
    if(~dp[u][st].fi) return dp[u][st];
    pii res = {INF, INF};
    for (int i = 0; i < n; ++i) {
        if(i == u) continue;
        if(st & (1<<i)) {
            pii p = dfs(i, st^(1<<u));
            p.se += d[i][u];
            if(p.se > w) p.fi++, p.se = s[u].size();
            if(p < res) {
                res = p;
                pre[u][st] = i;
            }
        }
    }
    if(res.fi == INF) res.fi = 0, res.se = s[u].size();
    return dp[u][st] = res;
}
int main() {
    fio;
    cin >> h >> w >> n;
    int tot = 0;
    for (int i = 0; i < n; ++i) cin >> t[i];
    for (int i = 0; i < n; ++i) {
        bool f = true;
        if(t[i].size() > w) return 0*puts("impossible");
        for (int j = 0; j < n; ++j) {
            if(i == j) continue;
            if(t[j].find(t[i]) == string::npos) continue;
            f = false;
        }
        if(f) s[tot++] = t[i];
    }
    n = tot;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if(i == j) continue;
            int mn = min(s[i].size(), s[j].size());
            d[i][j] = s[j].size();
            for (int k = 1; k <= mn; ++k) {
                if(s[i].substr(s[i].size()-k, k) == s[j].substr(0, k)) d[i][j] = s[j].size() - k; ///!!!!!!!!!
            }
        }
    }
    up = 1<<n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < up; ++j)
        dp[i][j] = {-1, -1}, pre[i][j] = -1;
    }
    for (int i = 0; i < n; ++i) {
        pii p = dfs(i, up-1);
        if(p.fi < h) {
            vector<string> res (h, string(w, ''X''));
            vector<int> p;
            int now = i, st = up-1;
            while(~now) {
                p.pb(now);
                now = pre[now][st];
                st ^= 1<<p.back();
            }
            reverse(p.begin(), p.end());
            pii pos = {0, 0};
            for (int i = 0; i < p.size(); ++i) {
                int x = p[i];
                if(i == 0) {
                    for (int j = 0; j < s[x].size(); ++j) res[pos.fi][pos.se+j] = s[x][j];
                    pos.se += s[x].size();
                }
                else {
                    int u = p[i-1];
                    if(pos.se + d[u][x] > w) {
                        pos.fi++;
                        pos.se = 0;
                        for (int j = 0; j < s[x].size(); ++j) res[pos.fi][pos.se+j] = s[x][j];
                        pos.se = s[x].size();
                    }
                    else {
                        int sz = s[x].size();
                        for (int j = 0; j < d[u][x]; ++j) res[pos.fi][pos.se+j] = s[x][sz-d[u][x]+j];
                        pos.se += d[u][x];
                    }
                }
            }
            for (int i = 0; i < h; ++i) cout << res[i] << endl;
            return 0;
        }
    }
    return 0*puts("impossible");
}
View Code

K You Are Fired

排序

代码:

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

/*

⊂_ヽ
  \\ Λ_Λ  来了老弟
   \(''ㅅ'')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
''ノ )  Lノ

*/

using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ''\n''

#define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);


const ll oo = 1ll<<17;
const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<''0''||ch>''9'') f|=(ch==''-''),ch=getchar();
    while (ch>=''0''&&ch<=''9'') x=x*10+ch-''0'',ch=getchar();
    return x=f?-x:x;
}

inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;}

/*-----------------------showtime----------------------*/
            const int maxn = 1e4+9;
            struct node{
                string name;
                ll x;
            }a[maxn];
            bool cmp(node a, node b){
                return a.x > b.x;
            }
int main(){
            ll n, d, k;
            cin>>n>>d>>k;
            rep(i,1, n)
            {
                cin>>a[i].name>>a[i].x;
            }
            sort(a+1,a+1+n,cmp);

            ll sum = 0;
            rep(i,1, k) sum += a[i].x;
            if(sum < d) puts("impossible");
            else {
                printf("%d\n", k);
                rep(i, 1, k) {
                    cout<<a[i].name<<", YOU ARE FIRED!"<<endl;
                }

            }
            return 0;
}
View Code

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

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

A. Drawing Borders

Unsolved.

 

B. Buildings

Unsolved.

 

C. Joyride

Upsolved.

题意:

在游乐园中,有 n 个游玩设施,有些设施之间有道路,给出每个设施需要花费的时间和价格,以及经过每条道路的时间,求从设施 1 出发恰好回到设施 1 恰好花费时间 x 的最小花费。

思路:

$dist [i][j] 表示 第 i 个时刻 到第 j 个点的最小花费  从 < t [1], 1> -> <x, 1>$

跑最短路即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 3010
 5 #define ll long long
 6 #define INF 0x3f3f3f3f3f3f3f3f
 7 int X, n, m, T, t[N], p[N]; 
 8 vector <int> G[N];
 9 
10 struct node
11 {
12     int x, to; ll w;
13     node () {}
14     node (int x, int to, ll w) : x(x), to(to), w(w) {}
15     bool operator < (const node &r) const { return w > r.w; }
16 };
17 
18 bool used[N][N]; 
19 ll dist[N][N];
20 void Dijkstra()
21 {
22     for (int i = 1; i <= X; ++i) for (int j = 1; j <= n; ++j) dist[i][j] = INF, used[i][j] = 0;
23     priority_queue <node> q; q.emplace(t[1], 1, 0); dist[t[1]][1] = p[1]; 
24     while (!q.empty())
25     {
26         int x = q.top().x, u = q.top().to; q.pop();
27         if (x > X) continue;
28         if (used[x][u]) continue;
29         used[x][u] = 1;
30         if (!used[x + t[u]][u] && dist[x + t[u]][u] > dist[x][u] + p[u]) 
31         {
32             dist[x + t[u]][u] = dist[x][u] + p[u];
33             q.emplace(x + t[u], u, dist[x + t[u]][u]);
34         }
35         for (auto v : G[u]) if (!used[x + t[v] + T][v] && dist[x + t[v] + T][v] > dist[x][u] + p[v])
36         {
37             dist[x + t[v] + T][v] = dist[x][u] + p[v];
38             q.emplace(x + t[v] + T, v, dist[x + t[v] + T][v]);
39         }
40     }    
41 }
42 
43 int main()
44 {
45     while (scanf("%d", &X) != EOF)
46     {
47         scanf("%d%d%d", &n, &m, &T);
48         for (int i = 1, u, v; i <= m; ++i)
49         {
50             scanf("%d%d", &u, &v);
51             G[u].push_back(v);
52             G[v].push_back(u);
53         }
54         for (int i = 1; i <= n; ++i) scanf("%d%d", t + i, p + i);
55         Dijkstra();
56         if (dist[X][1] == INF) puts("It is a trap.");
57         else printf("%lld\n", dist[X][1]);
58     }
59     return 0; 
60 }
View Code

 

D. Pants On Fire

Solved.

题意:

给出一些关系,再给出一些关系的询问,对于询问给出三种结果。

思路:

Floyd 求闭包,但是我还是想知道为什么拓扑排序不行,难道是题意读错,它不一定是个 DAG?

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 410
 5 int n, m; 
 6 map <string, int> mp; int cnt; 
 7 char a[N], b[N];
 8 int G[N][N]; 
 9 
10 int getid(char *s)
11 {
12     if (mp.find(s) == mp.end()) mp[s] = ++cnt;
13     return mp[s];
14 }
15 
16 void Floyd()
17 {
18     for (int k = 1; k <= cnt; ++k)
19     {
20         for (int i = 1; i <= cnt; ++i)
21         {
22             for (int j = 1; j <= cnt; ++j)
23             {
24                 if (G[i][k] & G[k][j])
25                     G[i][j] = 1;
26             }
27         }
28     }
29 }
30 
31 void init()
32 {
33     memset(G, 0, sizeof G); 
34     mp.clear(); cnt = 0; 
35 }
36 
37 int main()
38 {
39     while (scanf("%d%d", &n, &m) != EOF)
40     {
41         init();
42         for (int i = 1, u, v; i <= n; ++i)
43         {
44             scanf("%s are worse than %s", a, b);
45             u = getid(a), v = getid(b);
46             G[u][v] = 1;
47         }
48         Floyd(); 
49         //for (auto it : mp) cout << it.first << " " << rt[it.second] << " " << deep[it.second] << endl;
50         for (int i = 1, u, v; i <= m; ++i)
51         {
52             scanf("%s are worse than %s", a, b);
53             u = getid(a), v = getid(b);
54             if (G[u][v] == 1) puts("Fact");
55             else if (G[v][u] == 1) puts("Alternative Fact");
56             else puts("Pants on Fire");
57         }
58     }
59     return 0;
60 }
View Code

 

E. Perpetuum Mobile

Upsolved.

题意:

有 n 个转换器,m 个转换关系,转换关系是有向边

求从哪个点出发回到起点后经过的转换大于原来的值

思路:

枚举起点跑最长路,乘法可以取个 $log$, 当然也可以再取个负跑最短路也可以

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 10010
 5 #define INF 0x3f3f3f3f
 6 #define pid pair <int, double>
 7 int n, m;
 8 vector <pid> G[N];
 9 
10 struct node
11 {
12     int to; double w;
13     node () {}
14     node (int to, double w) : to(to), w(w) {}
15     bool operator < (const node &r) const { return w < r.w; }
16 };
17 
18 double dist[N]; bool used[N];
19 bool Dijkstra(int st)
20 {
21     for (int i = 1; i <= n; ++i) dist[i] = 0.0, used[i] = false;
22     priority_queue <node> q; q.emplace(st, 0);  
23     while (!q.empty())
24     {
25         int u = q.top().to; q.pop(); 
26         if (used[u] && u == st && dist[u] > 0) return false;  
27         if (used[u]) continue;
28         used[u] = 1;
29         for (auto it : G[u]) if (dist[it.first] < dist[u] + log(it.second)) 
30         {
31             dist[it.first] = dist[u] + log(it.second);
32             q.emplace(it.first, dist[it.first]);
33         }
34     }    
35     return true;
36 }
37 
38 bool solve()
39 {
40     for (int i = 1; i <= n; ++i) if (Dijkstra(i) == false)
41         return false; 
42     return true;
43 }
44 
45 int main()
46 {
47     while (scanf("%d%d", &n, &m) != EOF)
48     {
49         for (int i = 1; i <= n; ++i) G[i].clear();
50         double w;
51         for (int i = 1, u, v; i <= m; ++i)
52         {
53             scanf("%d%d%lf", &u, &v, &w);
54             G[u].emplace_back(v, w);
55         }
56         if (solve() == false) printf("in");
57         puts("admissible");
58     }
59     return 0;
60 }
View Code

 

F. Plug It In

Unsolved.

题意:

给出一个匹配关系,可以设置一个人和三个人匹配,求最大匹配数。

思路:

先求最大匹配,再枚举每个插座,找增广路,枚举点的时候都要复制原图备份一下

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1510
 5 int n, m, k;
 6 vector <int> G[N];
 7 int linker[N], vis[N], tmp[N];
 8 
 9 bool DFS(int u)
10 {
11     for (auto v : G[u]) if (!vis[v])
12     {
13         vis[v] = 1; 
14         if (linker[v] == -1 || DFS(linker[v]))
15         {
16             linker[v] = u;
17             return true;
18         }
19     }
20     return false;
21 }
22 
23 int main()
24 {
25     while (scanf("%d%d%d", &n, &m, &k) != EOF)
26     {
27         for (int i = 1; i <= n; ++i) G[i].clear();
28         for (int i = 1, u, v; i <= k; ++i)
29         {
30             scanf("%d%d", &u, &v);
31             G[u].push_back(v);
32         }
33         memset(linker, -1, sizeof linker);
34         int res = 0, ans = 0;
35         for (int i = 1; i <= n; ++i)
36         {
37             memset(vis, 0, sizeof vis);
38             if (DFS(i)) ++res;
39         }
40         memcpy(tmp, linker, sizeof linker);
41         for (int i = 1; i <= n; ++i)
42         {
43             int cnt = 0;
44             for (int j = 1; j <= 2; ++j)
45             {
46                 memset(vis, 0, sizeof vis);
47                 if (DFS(i)) ++cnt;    
48             }
49             ans = max(ans, cnt);
50             memcpy(linker, tmp, sizeof tmp);
51         }
52         printf("%d\n", res + ans);
53     }
54     return 0;
55 }
View Code

 

G. Water Testing

Upsolved.

题意:求一个多边形内部整点个数。

思路:

皮克定理:$S = a + \frac {b}{2} - 1   S 表示多边形面积,\frac {b}{2} 表示 多边形边上的整点数   a 表示多边形内部整点数 $

因为点是按顺序给出,有求面积公式 $S = \frac {1}{2} \sum_{i = 0}^{i = n}|\vec {P_i} x \vec {P_i - 1}|$

再考虑 线段上的整点个数为

$ 令 a = abs (stx - edx), b = abs (sty - edy),整点个数为 gcd (a, b) + 1$

考虑证明:

根据直线两点式有:

$y - y_1 = \frac{y_2 - y_1}{x_2 - x_1} \cdot (x - x _1)$

移项得

$y = \frac{y_2 - y_1}{x_2 - x_1} \cdot (x - x_1) + y_1$

即考虑 有多少个 $x 使得 (x - x_1) \equiv 0 \pmod {x_2 - x_1}$

由于 $x 在 [x1, x2] 范围内 那么 (x - x_1) 的范围即 [0, x2 - x1]$

$ 考虑 \frac {y_2 - y_1}{x_2 - x_1} 可以跟他们的 gcd 约分 $

$\frac{x_2 - x_1}{ \frac {x_2 - x_1}{gcd((y_2 - y_1), (x_2 - x_1))}} = gcd((y_2 - y_1), (x_2 - x_1))$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 #define ll long long
 6 int n; 
 7 ll x[N], y[N];
 8 
 9 ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a;}
10 
11 int main()
12 {
13     while (scanf("%d", &n) != EOF)
14     {
15         for (int i = 1; i <= n; ++i)
16             scanf("%lld%lld", x + i, y + i);
17         x[0] = x[n]; y[0] = y[n];
18         ll s = 0, b = 0;
19         for (int i = 1; i <= n; ++i)
20         {
21             s += x[i - 1] * y[i] - x[i] * y[i - 1];
22             ll A = abs(x[i] - x[i - 1]);
23             ll B = abs(y[i] - y[i - 1]);
24             b += gcd(A, B);
25         }
26         s = abs(s); 
27         printf("%lld\n", (s - b + 2) >> 1);  
28     }
29     return 0;
30 }
View Code

 

 

H. Ratatoskr

Unsolved.

 

I. Uberwatch

Water.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 300010
 5 int n, m, x[N], Max[15];
 6 
 7 int main()
 8 {
 9     while (scanf("%d%d", &n, &m) != EOF)
10     {
11         memset(Max, 0, sizeof Max);
12         for (int i = 1; i <= n; ++i) scanf("%d", x + i);
13         for (int i = m + 1, res; i <= n; ++i)
14         {
15             res = x[i] + Max[m];
16             for (int j = m; j >= 1; --j) Max[j] = max(Max[j], Max[j - 1]);
17             Max[1] = max(Max[1], res);
18         }
19         printf("%d\n", *max_element(Max + 1, Max + 1 + m));
20     }
21     return 0;
22 }
View Code

 

J. Word Clock

Unsolved.

 

K. You Are Fired

Water.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 10010
 5 int n, k, d;
 6 struct node
 7 {
 8     char s[10]; int c;
 9     void scan()
10     {
11         scanf("%s%d", s, &c);
12     }
13     bool operator < (const node &r) const {return c > r.c;}
14 }emp[N];
15 
16 int main()
17 {
18     while (scanf("%d%d%d", &n, &d, &k) != EOF)
19     {
20         for (int i = 1; i <= n; ++i) emp[i].scan();
21         sort(emp + 1, emp + 1 + n);
22         int tot = 0;
23         for (int i = 1; i <= k; ++i) tot += emp[i].c;
24         if (tot < d) puts("impossible");
25         else
26         {
27             printf("%d\n", k);
28             for (int i = 1; i <= k; ++i) printf("%s, YOU ARE FIRED!\n", emp[i].s);
29         }
30     }
31     return 0;
32 }
View Code

 

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) D bfs 思维 E bfs I Floyd 找最小环...

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) D bfs 思维 E bfs I Floyd 找最小环...

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)

题意:有 n 个人,每个人有 k 个特征,每个特征值为 0 或 1。 定义两人的相似度为:k 个特征值中相同的个数。 要你另外找一个人,这个人和其他人相似度的最大值要尽可能小。

tags:bfs,思维

找一个人与其他人相似度的最大值尽可能小,也就是这个人与其他人 不相似度的最小值要尽可能大。

那我们可把这 n 个人当成 n 个点,总共有 (1<<k) 个点。我们以这 n 个点为起点 bfs,每走一步改变一个特征值,即 不相似度 +1 。最后找 不相似度最大的就是了。

//  D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 2000005;

int n, k, dis[N];
char str[N];
queue< int > q;
void bfs()
{
    int u, to;
    while(!q.empty())
    {
        u = q.front();  q.pop();
        rep(j,1,k)
        {
            to = u^(1<<(j-1));
            if(dis[to]==-1) {
                dis[to] = dis[u]+1;
                q.push(to);
            }
        }
    }
}
int main()
{
    scanf("%d%d", &n, &k);
    mes(dis, -1);
    rep(i,1,n)
    {
        scanf("%s", str+1);
        int tmp = 0;
        rep(j,1,k)
            if(str[j]==''1'') tmp+=1<<(j-1);
        dis[tmp]=0;   q.push(tmp);
    }
    bfs();
    int ans1, ans2=0;
    rep(i,0,(1<<k)-1)
        if(dis[i]>=ans2) ans1=i, ans2=dis[i];
    rep(j,1,k)
        if((ans1>>(j-1))&1) putchar(''1'');
        else putchar(''0'');

    return 0;
}
View Code

 

E

题意:n*m 的地方,每个地方给出高度,所有 n*m 的地方有海拔为 0 的积水。 现在给出一个点作为排水口,每个地方的水可以往周围八个方向,且比它低的地方流。问最后会流走多少水。

tags:bfs 跑一遍,同时要记录每个点可以下降到的最低点,且优生走更低的点。

//  E
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 505;

int n, m, a[N][N], ans[N][N];
struct Node {
    int x, y, h;
    bool friend operator<(Node a, Node b) {
        return a.h > b.h;
    }
};
int dirx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
int diry[8] = {0, 0, 1, -1, 1, -1, -1, 1};
priority_queue< Node > q;
bool check(int x, int y) {
    return x>0 && x<=n && y>0 && y<=m;
}
void bfs(int x, int y, int h)
{
    Node u;
    q.push((Node){ x,y,h });
    int tx, ty;
    while(!q.empty())
    {
        u = q.top();  q.pop();
        x=u.x, y=u.y, h=u.h;
        if(ans[x][y]<h) continue;
        rep(i,0,7)
        {
            tx=x+dirx[i],  ty=y+diry[i];
            if(check(tx,ty) && max(a[tx][ty],h)<0 && ans[tx][ty]>max(a[tx][ty],h))
            {
                ans[tx][ty] = max(h, a[tx][ty]);
                q.push((Node){ tx,ty,ans[tx][ty] });
            }
        }
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    rep(i,1,n) rep(j,1,m)
        scanf("%d", &a[i][j]);
    int tx, ty;
    scanf("%d%d", &tx, &ty);
    ans[tx][ty]=min(0, a[tx][ty]);
    bfs(tx, ty, a[tx][ty]);
    ll  ans1 = 0;
    rep(i,1,n) rep(j,1,m)
        if(ans[i][j]<0)
            ans1 += -ans[i][j];
    printf("%lld\n", ans1);

    return 0;
}
View Code

 

题意: n 个文件,每个文件可以调用多个其它的文件,问最小的循环调用,且输出路径。 也就是在 DAG 图中找一个最小环。

tags:套板子 -_-

Floyd 有向图找最小环

// Floyd 找有向图最小环
const int N = 505;
int G[N][N], n ,m, dist[N][N], past[N][N];
int mincircle, path[N], cnt;
void Init_Floyd()
{
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            G[i][j] = INF;
}
void Floyd()
{
    mincircle = INF;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            dist[i][j] = G[i][j], past[i][j] = i;

    for(int k = 1; k <= n; k++)  //每个点都成为一次中间点,但和bellman-ford不一样
    {
        for(int i = 1; i <= n; i++) //判断是不是最小环
            for(int j = 1; j <= n; j++)
            {
                if(i == j)  continue;
                if(dist[i][j]!=INF && G[j][k]!=INF && G[k][i]!=INF && mincircle>dist[i][j]+G[j][k]+G[k][i])
                {
                    mincircle = dist[i][j]+G[j][k]+G[k][i];
                    cnt = 0;
                    int  p=j;
                    while(p!=i) //逆向寻找前驱结点直到找到最前面的i,i->…->j
                    {
                        path[cnt++]=p;
                        p=past[i][p];
                    }
                    path[cnt++]=i;
                    path[cnt++]=k;
                }
            }

        for(int i = 1; i <= n; i++) // 这里就是 Floyd算法
            for(int j = 1; j <= n; j++)
            {
                if(i == k || j == k)  continue;
                if(dist[i][k]!=INF && dist[k][j]!=INF && dist[i][j]>dist[i][k]+dist[k][j])
                {
                    dist[i][j] = dist[i][k]+dist[k][j];
                    past[i][j] = past[k][j];
                }
            }
    }
}
void print_path()
{
    if(mincircle==INF || mincircle<0)
        puts("-1");
    else {
        for(int i=cnt-1; i>=0; --i)
            printf("%d ", path[i]);
        puts("");
    }
}
//   I
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 505;

int grap[N][N] , n , m;
int dist[N][N];
int past[N][N];
int mincircle;
int path[N] , k1 ;
void Init_Floyd()
{
    int i , j;
    for(i = 1; i <= n; i++)
        for(j = 1; j <= n; j++)
            grap[i][j] = INF;
}
void Floyd()
{
    mincircle = INF;
    int i , j;
    for(i = 1; i <= n; i++)
        for(j = 1; j <= n; j++)
        {
            dist[i][j] = grap[i][j];
            past[i][j] = i;
        }

    for(int k = 1; k <= n; k++)  //每个点都成为一次中间点 , 和bellman-ford不一样
    {
        for(i = 1; i <= n; i++) //判断是不是最小环
            for(j = 1; j <= n; j++)
            {
                //if(i == j)  continue;
                if(dist[i][j]!=INF && grap[j][k]!=INF && grap[k][i]!=INF && mincircle>dist[i][j]+grap[j][k]+grap[k][i])
                {
                    mincircle = dist[i][j]+grap[j][k]+grap[k][i];
                    k1 = 0;
                    int  p=j;
                      while(p!=i) //逆向寻找前驱结点直到找到最前面的i,i->…->j
                      {
                            path[k1++]=p;
                            p=past[i][p];//fa[i][j]保存的不是k,而是fa[k][j].
                      }
                      path[k1++]=i;
                      path[k1++]=k;
                }
            }

        for(i = 1; i <= n; i++) //Floyd算法
            for(j = 1; j <= n; j++)
            {
                //if(i == k || j == k)  continue;
                if(dist[i][k]!=INF && dist[k][j]!=INF && dist[i][j]>dist[i][k]+dist[k][j])
                {
                    dist[i][j] = dist[i][k]+dist[k][j];
                    past[i][j] = past[k][j];
                }
            }
    }
}

string str;
char si[N];
map<string , int > mp;
map<int , string > mp2;
int main()
{
    scanf("%d", &n);
    Init_Floyd();
    rep(i,1,n) {
        scanf("%s", si);   str = si;
        mp[str]=i,  mp2[i]=str;
    }
    int k, u, len, to;
    bool flag;
    rep(i,1,n)
    {
        scanf("%s%d", si, &k);  str = si;
        u = mp[str];
        rep(j,1,k)
        {
            scanf("%s", si);
            while(~scanf("%s", si))
            {
                flag = false;
                len = strlen(si);
                if(si[len-1]=='','') {
                    flag=true;
                    si[len-1]=''\0'',  --len;
                }
                str = si;
                to = mp[str];
                if(grap[u][to]>1)
                    grap[u][to]=1;
                if(!flag) break;
            }
        }
    }
    rep(i,1,n) if(grap[i][i]<INF) {
        cout<<mp2[i]<<endl;
        return 0;
    }
    rep(i,1,n) rep(j,1,n)
    {
        if(i!=j && grap[i][j]==1 && grap[j][i]==1) {
            cout<<mp2[i]<<" "<<mp2[j]<<endl;
            return 0;
        }
    }
    Floyd();
    if(mincircle==INF || mincircle<0)
        puts("SHIP IT");
    else {
        for(int i=k1-1; i>=0; --i)
            cout<<mp2[path[i]]<<" ";
        puts("");
    }

    return 0;
}
View Code

 

K

题意:有三种人,要过河,三种人分别有 b, n, e 个,每种人的系数是 sb,sn,se,有 (b+n+e)/2 条船,第 i 条船有速度 ci。每条船上坐两个人 x, y ,这条船的速度就是 ci*(sx+sy)。要你分配人和船,使得速度最小的船的速度要尽可能大。

tags:二分答案,然后 O (n) 贪心 check。

// k
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;

int n, m, a[5], b[5], a2[5], c[N];
int cnt;
pair<int , pair<int, int >  > p[10];
bool check(int x)
{
    rep(i,1,3) a2[i]=a[i];
    rep(i,1,m)
    {
        bool flag=false;
        rep(j,1,cnt)
        {
            int t1=p[j].se.fi, t2=p[j].se.se;
            if(t1!=t2 && (a2[t1]<1 || a2[t2]<1)) continue;
            if(t1==t2 && a2[t1]<2) continue;
            if(c[i]*p[j].fi >= x)
            {
                --a2[t1], --a2[t2];
                flag=true;  break;
            }
        }
        if(!flag) return false;
    }
    return true;
}
int main()
{
    rep(i,1,3) scanf("%d", &a[i]), m+=a[i];
    m /= 2;
    rep(i,1,3) scanf("%d", &b[i]);
    rep(i,1,m) scanf("%d", &c[i]);
    sort(c+1, c+1+m);
    rep(i,1,3) rep(j,i,3)
        p[++cnt]=MP(b[i]+b[j], MP(i,j));
    sort(p+1, p+1+cnt);
    int l=c[1]*(b[1]+b[1]), r=c[m]*(b[3]+b[3]), mid, ans;
    while(l<=r)
    {
        mid = l+r>>1;
        if(check(mid)) ans=mid, l=mid+1;
        else r=mid-1;
    }
    printf("%d\n", ans);

    return 0;
}
View Code

 

今天的关于2017 Android 和 iOS 频频被曝 Bug,它们都怎么了?2017安卓的分享已经结束,谢谢您的关注,如果想了解更多关于(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)、2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)、2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Solution、2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) D bfs 思维 E bfs I Floyd 找最小环...的相关知识,请在本站进行查询。

本文标签: