PRank3

  • 窝太水了..
  • 搞不动了- -

A Quicksum

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX = 512;
char buffer[MAX];

int main()
{
    int len;
    while (fgets(buffer, MAX, stdin) != NULL)
    {
        //printf("read %s\n", buffer);
        if (buffer[0] == ‘#‘)
        {
            break;
        }
        len = strlen(buffer);

        int sum = 0;
        for (int i = 0; i + 1 < len; ++i)
        {
            sum += (buffer[i] == ‘ ‘ ? 0 : buffer[i] - ‘A‘ + 1) * (i + 1);
        }
        printf("%d\n", sum);
    }
    return 0;
}

B Asteroids

  • 二分图最大匹配
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX = 512;
int G[MAX][MAX];
int match[MAX];
bool vis[MAX];
int n, k;

int dfs(int v)
{
    int t;
    for (int i = 1; i <= n; ++i)
    {
        if (G[i][v] && !vis[i])
        {
            vis[i] = true;
            t = match[i];
            match[i] = v;
            if (t == -1 || dfs(t))
            {
                return 1;
            }
            match[i] = t;
        }
    }
    return 0;
}

int main()
{
    while (~scanf(" %d %d", &n, &k))
    {
        memset(G, 0, sizeof(G));
        int x, y;
        for (int i = 0; i < k; ++i)
        {
            scanf(" %d %d", &x, &y);
            G[x][y] = 1;
        }

        int ans = 0;
        memset(match, -1, sizeof(match));
        for (int i = 1; i <= n; ++i)
        {
            memset(vis, false, sizeof(vis));
            ans += dfs(i);
        }
        printf("%d\n", ans);
    }
    return 0;
}

C NastyHacks

#include <cstdio>
#include <cstring>

int main()
{
    int T;
    scanf(" %d", &T);
    while (T--)
    {
        int r, e, c;
        scanf(" %d %d %d", &r, &e, &c);
        if (e - c == r)
        {
            puts("does not matter");
        }
        else if (e - c > r)
        {
            puts("advertise");
        }
        else
        {
            puts("do not advertise");
        }
    }

    return 0;
}

F ScoutYYFI

  • operator?时忘了写返回语句…
  • 早知道开-Wall了…
  • 妈蛋p.p

    / \

    / \

    /  \

  • 首先

    dp[n]=dp[n?1]?p+dp[n?2]?(1?p)
  • 然后我们知道,炸弹将道路分成了若干段,设炸弹位置为pos[i],我们要做的就是分段考虑pos[j]→pos[j+1],当然了,第一段是1→pos[0]额外算
  • 在每一段[a,b]上存活的概率都是

    dp[b?1]?(1?p)
  • 各段相乘即可。对某一段,用矩阵快速幂加速。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long ll;
struct Mat
{
    double a[2][2];
    Mat operator*(const Mat& B)const
    {
        Mat res;
        for (int i = 0; i < 2; ++i)
        {
            for (int j = 0; j < 2; ++j)
            {
                res.a[i][j] = 0.0;
                for (int k = 0; k < 2; ++k)
                {
                    res.a[i][j] += a[i][k] * B.a[k][j];
                }
            }
        }
        return res;
    }
    void print()
    {
        for (int i = 0; i < 2; ++i)
        {
            for (int j = 0; j < 2; ++j)
            {
                printf("%.2f ", a[i][j]);
            }
            puts("");
        }
    }
};

Mat fast_pow(Mat A, ll n)
{
    Mat res;
    res.a[0][0] = res.a[1][1] = 1.0;
    res.a[0][1] = res.a[1][0] = 0.0;
    while (n > 0)
    {
        if (n & 1)
        {
            res = res * A;
        }
        A = A * A;
        //res.print();
        //A.print();
        //printf("n = %lld\n", n);
        //puts("---------");
        n >>= 1;
    }
    return res;
}

int n;
double p;

double gao(ll from, ll to)
{
    ll n = to - from + 1;
    if (n == 1)
    {
        return 1.0;
    }
    else if (n <= 0)
    {
        return 0.0;
    }
    Mat mm;
    mm.a[0][0] = p;
    mm.a[0][1] = 1.0;
    mm.a[1][0] = 1.0 - p;
    mm.a[1][1] = 0.0;

    Mat A;
    A.a[0][0] = 1.0;
    A.a[0][1] = 0.0;
    A.a[1][0] = 1.0;
    A.a[1][1] = 1.0;

    A = A * (fast_pow(mm, n - 1));
    return A.a[0][0];
}

int main()
{
    vector<ll> pos;
    while (~scanf(" %d %lf", &n, &p))
    {
        pos.clear();
        ll pp;
        for (int i = 0; i < n; ++i)
        {
            scanf(" %lld", &pp);
            pos.push_back(pp);
        }
        sort(pos.begin(), pos.end());
        if (pos[0] == 1)
        {
            puts("0.0000000");
            continue;
        }
        ll left = 1;
        double ans = 1.0;
        for (int i = 0; i < n; ++i)
        {
            ans *= gao(left, pos[i] - 1);
            ans *= 1.0 - p;
            left = pos[i] + 1;
        }
        printf("%.7f\n", ans);
    }
    return 0;
}

D HardLife

  • 这啥?不知道
  • 是最大密度子图
  • 模板
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=400,M=5000;
const double inf=1e10,eps=1e-6;
int head[N],nc,du[N];
struct data
{
    int x,y;
}po[M];
struct edge
{
    int x,y,next;
    double cap;
} edge[M*3];
void add(int x,int y,double cap)
{
    edge[nc].x=x;
    edge[nc].y=y;
    edge[nc].cap=cap;
    edge[nc].next=head[x];
    head[x]=nc++;
    edge[nc].x=y;
    edge[nc].y=x;
    edge[nc].cap=0;
    edge[nc].next=head[y];
    head[y]=nc++;
}
int num[N],h[N],S,T,n,m;
double findpath(int x,double flow)
{
    if(x==T)
        return flow;
    double res=flow;
    int pos=n-1;
    for(int i=head[x]; i!=-1; i=edge[i].next)
    {
        int y=edge[i].y;
        if(h[x]==h[y]+1&&edge[i].cap>eps)
        {
            double
                tp=findpath(y,min(edge[i].cap,res));
            res-=tp;
            edge[i].cap-=tp;
            edge[i^1].cap+=tp;
            if(res<eps||h[S]==n)
                return flow-res;
        }
        if(edge[i].cap>eps&&h[y]<pos)
            pos=h[y];
    }
    if(abs(res-flow)<eps)
    {
        num[h[x]]--;
        if(num[h[x]]==0)
        {
            h[S]=n;
            return flow-res;
        }
        h[x]=pos+1;
        num[h[x]]++;
    }
    return flow-res;
}
double Sap(double x)
{
    memset(head,-1,sizeof(head));
    nc=0;
    for(int i=0;i<m;i++)
    {
        add(po[i].x,po[i].y,1.0);
        add(po[i].y,po[i].x,1.0);
    }
    for(int i=1;i<T;i++)
    {
        add(S,i,(double)m);
        add(i,T,(double)m+2*x-(double)du[i]);
    }
    double ans=0;
    memset(h,0,sizeof(h));
    memset(num,0,sizeof(num));
    while(h[S]!=n)
        ans+=findpath(S,(T-1)*m);
    return (T-1.0)*m-ans;
}
bool vis[N];
int dfs(int now)
{
    int cnt=1;
    vis[now]=true;
    for(int i=head[now];i!=-1;i=edge[i].next)
    {
        if(!vis[edge[i].y]&&edge[i].cap>eps)
        {
            cnt+=dfs(edge[i].y);
        }
    }
    return cnt;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(du,0,sizeof(du));
        S=0;T=n+1;n=T+1;
        for(int i=0; i<m; i++)
        {
            scanf("%d%d",&po[i].x,&po[i].y);
            du[po[i].x]++;du[po[i].y]++;
        }
        if(m==0)
        {
            printf("1\n1\n");
            continue;
        }
        double ll=0,rr=(double)m,mid;
        while(rr-ll>1.0/(T-1.0)/(T-1.0))
        {
            mid=(ll+rr)/2.0;
            double tp=Sap(mid);
            if(abs(tp)<eps)
                rr=mid;
            else
                ll=mid;
        }
        memset(vis,false,sizeof(vis));
        int ans=dfs(S)-1;
        if(ans==0)
        {
            Sap(ll);
            memset(vis,false,sizeof(vis));
            ans=dfs(S)-1;
        }
        printf("%d\n",ans);
        for(int i=1;i<T;i++)
            if(vis[i])
                printf("%d\n",i);
    }
    return 0;
}

一把辛酸泪

  • 孩子,加油…

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 21:53:09

PRank3的相关文章