UESTC 2014 Summer Training #10 Div.2

B.Race to 1 UVA 11762

  第一次接触概率dp,完全没想到是dp...没想到能递推出来0 0

  首先需要知道 总的期望=每件事的期望×每件事发生的概率

  然后可以根据这个来写递推公式,也是dp?

  假设不小于x的质数有m个,x的质因子有n个(种 更确切),那么在求X的期望时,可以考虑由他能转移过去的状态转移,X,X/pi p是x的质因子

  所以不难得出E(x) = 1+(m-n)/mE(X)+1/msigmaE(X/pi)  注意会加1,因为X转移到后面的情况,就多了一步

//Updated:  每个case跑完了,f数组不用memset...会快10倍!uva数据的情况下

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

const int maxn = 1000000+50;
const double eps = 1e-10;

int T, N, tot;
int prime[maxn];
double f[maxn];
bool flag[maxn], done[maxn];

void getPrime()
{
    for(int i = 2; i < maxn; i++) {
        if(!flag[i])    prime[tot++] = i;
        for(int j = 0; j < tot && prime[j]*i < maxn; j++) {
            flag[i*prime[j]] = true;
            if(i % prime[j] == 0)    break;
        }
    }
}

double dp(int x)
{
    if(done[x])    return f[x];
    done[x] = true;
    int n, m;
    n = m = 0;
    for(int i = 0; i < tot && prime[i] <= x; i++) {
        n++;
        if(x % prime[i] == 0) {
            m++;
            f[x] += dp(x/prime[i]);
        }
    }
//    if(x == N)    cout << n << ‘ ‘ << m << endl;
    return f[x] = (f[x]+n)/m;
}

int main()
{
#ifdef LOCAL
    freopen("B.in", "r", stdin);
#endif
    getPrime();
    scanf("%d", &T);
    for(int t = 1; t <= T; t++) {
        scanf("%d", &N);
        memset(done, 0, sizeof(done));
        memset(f, 0, sizeof(f));
        f[1] = 0.0;    done[1] = true;
        dp(N);
        printf("Case %d: %.10lf\n", t, f[N]);
    }
    return 0;
}

D.Jumping Mario UVA 11764

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

int T, n, now, high, low;

int main()
{
    cin >> T;
    for(int t = 1; t <= T; t++) {
        high = 0;
        low = 0;
        cin >> n;
        for(int i = 0; i < n; i++) {
            int x;
            cin >> x;
            if(i == 0) {
                now = x;
                continue;
            }
            if(x > now)    high++;
            else if(x < now)    low++;
            now = x;
        }
        cout << "Case " << t << ": " << high << ‘ ‘ << low << endl;
    }
    return 0;
}

J.Lighting Away UVA 11770

  第一反应的确是强连通分量...缩点...但是我不太熟...所以就去yydfs的方法,可是智商不够用...最后没调试出来

  正解就是缩点染色判断新的图入读为0的点

  调试了很久很久...各种小错误都发现了,最后倒在了出栈忘记加大括号了...

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <cstring>

using namespace std;

const int maxn = 100000+50;

int T, n, m, idx, tot, cnt;
int head[maxn], next[maxn], edge[maxn], dfn[maxn], low[maxn], in[maxn], type[maxn];
bool instack[maxn], visit[maxn];
stack<int> st;

void add(int u, int v)
{
    edge[tot] = v;
    next[tot] = head[u];
    head[u] = tot++;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++idx;
    st.push(u);
    instack[u] = true;
    visit[u] = true;
    for(int e = head[u]; e != -1; e = next[e]) {
        int v = edge[e];
        if(!visit[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(instack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u]) {
        cnt++;
        while(!st.empty())
        {
            int now=st.top();    st.pop();
            instack[now]=0;
            type[now]=cnt;
            if(now == u) break;
        }
    }
}

int main()
{
#ifdef LOCAL
    freopen("J.in", "r", stdin);
#endif
    scanf("%d", &T);
    for(int t = 1; t <= T; t++) {
        scanf("%d%d", &n, &m);
        memset(next, -1, sizeof(next));
        memset(head, -1, sizeof(head));
        memset(in, 0, sizeof(in));
        memset(instack, 0, sizeof(instack));
        memset(visit, 0, sizeof(visit));
        tot = 0;    idx = 0;    cnt = 0;
        for(int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
        }
//        for(int i = 1; i <= n; i++)
//            if(!visit[i] && in[i] == 0)    tarjan(i);

        for(int i = 1; i <= n; i++)
            if(!visit[i])    tarjan(i);
        int ans = 0;
        for(int i = 1; i <= n; i++)
            for(int e = head[i]; e != -1; e = next[e]) {
                if (type[i] != type[edge[e]]) in[type[edge[e]]]++;
            }
        for (int i = 1;i <= cnt;i++)
            if (in[i] == 0) ans++;
//        for(int i = 1; i <= n; i++)
//            if(in[i] == 0)    cnt++;
        printf("Case %d: %d\n", t, ans);

    }
    return 0;
}

  这场比赛做的时候只出了道水题...然后J和B是真的实力不够...J就是后来搞也有很多迷糊的地方,现在算是搞懂了

时间: 2024-10-17 12:24:53

UESTC 2014 Summer Training #10 Div.2的相关文章

UESTC 2014 Summer Training #3 Div.2

(更新中) A:ZOJ 3611 BFS+状态压缩 [题意]:给定一张n*m的图,图上每个点有如下情况:L,R,D,U:代表在该点上只能往它已经给定的方向前进.#,W:不能走到该点.$:走到该点,可以花两分钟得到一分值,然后可以从该点向任意方向走.0:走到该点后可以向任意方向走.然后给你起点和终点坐标,问是否能从起点走到终点,如果能,求出可获得的最大分值以及与之对应达到该最大分值所需的的最小时间花 费.(其中起点和终点坐标可以相同)[知识点]:BFS+状态压缩[题解]:我觉得超级棒的题!真心感觉

UESTC 2014 Summer Training #16 Div.2

虽然被刷了还是要继续战斗下去嗯...就是基础不好,难度相对较大 A.SPOJ AMR10A 点是顺时针给出的,可以在图上画画(脑补也行),连线x-a,x-b(x为选定的一个点,比如第一个点),就把所求面积分成了四部分,a-b左边部分是较容易求出来的, 三角形面积是直接可求,另外两个多边形面积是可以预处理出来的(多个三角形面积和) 反正我是沒想出來...看題解也理解半天,多邊形面積转化为三角形面积和 嗯嗯 #include <iostream> #include <cstdio> #

UESTC 2014 Summer Training #7 Div.2

DAY7一开始状态还行,最高纪录rank7,然后没力气了,一直跌到rank24,问题还是很多呐.昨天总结的问题依然很大. Problem A UVA 12377 就一开始还是慌了,没审清楚题意就去WA了一发. 大意是给你一个数字表示的字符串,最高20位,第一表示有N个质数,后面是其幂的非降序排列,所求能表示的数个数. 简单的排列组合题,不过需要处理出2~END的不同划分,并且满足非降序,用dfs处理即可. 具体就是dfs过程中记录下每一个数字出现的次数,因为相同的次数是不计顺序的,需要在统计时除

UESTC 2014 Summer Training #5 Div.2

持续更新中 B:URAL 1874 三分搜索 [题意]: 给出两条边a,b以及一个墙角,求由这两条边和墙角所构成的四边形的最大面积.[知识点]: 三分搜索[题解]: 将四边形分为两个三角形,其中一个由a,b,以及第三条同时作为墙角斜边的边c,另一个三角形即为墙角与边c构成 则墙角所在的三角形的最大面积为c*c/4,abc变所在的三角形的面积可用海伦公式求出,然后主要是用三分来求这个c,得到c后就可以得到最佳答案了. 还有一种现成的结论...[代码1]: 1 #include <map> 2 #

UESTC 2014 Summer Training #6 Div.2

又是只过两水题,不过状态有些回升,也是差点一血. Problem A SPOJ AMR11A 显然的dp?就一抖就想到尝试从(R,C)推到(1,1),正着推的话,只能检查某一种解可不可行(就有人想出了二分+DP的神奇方法..刚卡过..不过上界是把所有龙加起来..不闲麻烦的话..可以按照贪心的方法先跑一个上界,就每一步选当前最优) 倒着推,龙的话,就加上,药水的话,减去?不够,和1取最大值:某一个点的f[i][j]就是两种策略取最小值: f[i][j] = min{ max(1, f[i+1][j

UESTC 2014 Summer Training #18 Div.2

A.UVALive 6661 题意从1~N中选k个数,和为s的方案数 第一眼搜索,估计错状态量,又去yydp...浪费大量时间 数据很小的,状态数都不会超过2^N...直接dfs就过了 //state二进制表示选取的数 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn = 200; in

UESTC 2014 Summer Training #11 Div.2

E - Prototype ZOJ 3235 把(d2,0)代入第二个方程可以得到一个方程:经过(d2,0)的抛物线的起点的方程 再把它和第一个方程联立,就能解出两条抛物线的交点,再验算:是否在0~d2范围内,是否在x=d1时会撞到building2 注意可能不需要滑行就能到达(d2,0),先特殊处理这种情况 一开始傻逼理解错题意,后来一直修改又去考虑了不会出现的情况,例如A=0,delta<0,最后才发现了我忘记打sqrt了!!! 这场比赛题略难...就不会做 当时还是比较慌,很怕过不了题,加

UESTC 2014 Summer Training #19

A.UVALive 6161 去迟了,队友已经开始写了,应该是个水题,贴个队友代码 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inclu

2014 Super Training #10 G Nostop --矩阵快速幂

原题: FZU 2173 http://acm.fzu.edu.cn/problem.php?pid=2173 一开始看到这个题毫无头绪,根本没想到是矩阵快速幂,其实看见k那么大,就应该想到用快速幂什么的,况且n<=50,可以用矩阵来表示图. 1.为什么能用矩阵快速幂呢? 原理: 原始矩阵m[][]中,m[u][v]代表u到v的花费,求矩阵的k次幂后,此时m[u][v]代表,从u走向b经过v步的最少花费注意此时矩阵的相乘应该写成:m[a][b]=min(m[a][1]+m[1][b],...m[