码迷,mamicode.com
首页 > 其他好文 > 详细

紫书第10章存题

时间:2015-05-08 22:01:09      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:uva   算法竞赛入门经典第二版   紫书   

UVA 580 枚举出现连续3个U第一次出现的位置。同时需要记录前i位不出现连续3个u的方案。

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 20 + 10;
ll f[maxn],g[maxn];
ll quick(ll a,int n)
{
    ll res = 1;
    while(n) {
        if(n&1) res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}
void init(int n)
{
    f[0] = f[1] = f[2] = 0;
    g[0] = 1;g[1] = 2;g[2] = 4;
    for(int i = 3; i <= n; ++i) {
        f[i] = quick(2,i-3);
        for(int j = 2; j <= i-2; ++j) {
            f[i] += g[j-2]*quick(2,i-j-2);
        }
        g[i] = quick(2,i) - f[i];
    }
}
int main(int argc, char const *argv[])
{
    init(30);
    int n;
    while(~scanf("%d",&n)&&n) {
        printf("%lld\n", f[n]);
    }
    return 0;
}


UVA 12034 n人比赛,最终名次方案数,枚举第一名并列人数,缩小规模。

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
int c[maxn][maxn],res[maxn];
const int mod = 10056;
void init(int n)
{
    for(int i = 0; i <= n; ++i) {
        c[i][0] = 1;
        for(int j = 1; j <= i; ++j)
            c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;
        c[i][i+1] = 0;
    }
    res[0] = 1;
    for(int i = 1; i <= n; i++) {
        res[i] = 0;
        for(int j = 1; j <= i; j++)
            res[i] = (res[i] + c[i][j]*res[i-j])%mod;
    }
}
int main(int argc, char const *argv[])
{
    init(1000);
    int T; scanf("%d",&T);
    for(int cas = 1,n; cas <= T; ++cas) {
        scanf("%d",&n);
        printf("Case %d: %d\n", cas, res[n]);
    }
    return 0;
}

UVA 1639 注意用long doule提高精度


#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn = 5e3 + 10;
typedef long long ll;
int main()
{
    int n; long double p;
    int cas = 1;
    while(cin>>n>>p) {
        if(p==1.0||p==0.0) {
            printf("Case %d: %.6f\n",cas++,1.0*n);
            continue;
        }
        long double res = 0;
        long double t = 0;
        for(int i = 1; i <= n; i++) t += log(2*n-i+1.0)-log(n-i+1.0);
        int dy = 2*n,dx = n;
        for(int i = 1; i <= n; i++) {
            t += log(dx--) - log(dy--);
            double v1 = t + (n+1)*log(p)+(n-i)*log(1-p);
            double v2 = t + (n+1)*log(1.0-p)+(n-i)*log(p);
            res += i*(exp(v1)+exp(v2));
        }
        printf("Case %d: %.6f\n",cas++,(double)res);
    }
    return 0;
}


UVA11440欧拉函数,需要求n!的欧拉函数值,递推求

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define pb push_back
const int maxn = 10000000 + 10;
typedef long long ll;
const ll mod = 100000007;
int phifac[maxn];
bool vis[maxn];
void init(int n)
{
    memset(vis,0,sizeof vis);
    for(ll i = 2; i <= n; i++) if(!vis[i]) {
        for(ll j = i*i; j <= n; j += i) vis[j] = 1;
    }
    phifac[1] = 1;
    for(int i = 2; i <= n; i++)
        phifac[i] = (ll)phifac[i-1]*(vis[i]?i:i-1)%mod;
}
int gao(int n,int m)
{
    int res = phifac[m];
    for(ll i = m+1; i <= n; i++) res = ((ll)res*i)%mod;
    return (res-1+mod)%mod;
}
int main (){
    int n,m;
    init(maxn-10);
    while(~scanf("%d%d",&n,&m)&&(n+m)) {
        printf("%d\n",gao(n,m));
    }
    return 0;
}

UVA 10214欧拉函数应用需要注意gcd(x+i,x) = gcd(x,i)

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 2000 + 10;
typedef long long ll;
const ll mod = 100000007;
int phi[maxn];
void init(int n)
{
    memset(phi,0,sizeof phi);
    phi[1] = 1;
    for(int i = 2; i <= n; i++)if(!phi[i]){
        for(int j = i; j <= n; j+=i) {
            if(!phi[j])phi[j] = j;
            phi[j] = phi[j]/i*(i-1);
        }
    }
}
int gcd(int a,int b) {
    while(a&&b) {
        if(a>b)a%=b;
        else b%=a;
    }
    return a + b;
}
double gao(int a,int b)
{
    long double res = 0;
    if(a>b)swap(a,b);
    for(int x = 1; x <= a; x++) {
        ll t = b/x;
        res += phi[x]*t;
        for(int y = t*x+1; y <= b; y++)if(gcd(x,y)==1) {
            res = res + 1;
        }
    }
    ll t = (2.0*a+1)*(2.0*b+1)-1;
    return (4.0+4.0*res)/t;
}
int main (){
    int n,m;
    init(maxn-10);
    while(~scanf("%d%d",&n,&m)&&n&&m) {
        printf("%.7lf\n",gao(n,m));
    }
    return 0;
}


UVA 1642 动态维护gcd值左端点,gcd值只有logn 个,可以直接暴力维护去重

#include <bits/stdc++.h>
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
using namespace std;
typedef long long ll;
int main()
{
    int T;scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        vector<ll>gcd;
        ll ans = 0;
        vector<int>L;
        for(int i = 1; i <= n; i++) {
            ll x;scanf("%lld",&x);
            ans = max(ans,x);
            bool found = 0;
            for(int j = 0; j < gcd.size(); j++) {
                gcd[j] = __gcd(gcd[j],x);
                if(gcd[j]==x)found = true;
                ans = max(gcd[j]*(i-L[j]+1),ans);
            }
            if(!found) {
                gcd.push_back(x);
                L.push_back(i);
            }
            vector<pair<ll,int> >t;
            for(int i = 0; i < gcd.size(); i++) {
                bool ok = false;
                for(int j = 0; j < t.size(); j++) {
                    if(gcd[i]==t[j].first) {
                        ok = true;
                        t[j].second = min(t[j].second,L[i]);
                        break;
                    }
                }
                if(!ok)t.push_back(make_pair(gcd[i],L[i]));
            }
            gcd.resize(t.size());
            L.resize(t.size());
            for(int j = 0; j < t.size(); ++j){
                gcd[j] = t[j].first;
                L[j] = t[j].second;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


紫书第10章存题

标签:uva   算法竞赛入门经典第二版   紫书   

原文地址:http://blog.csdn.net/acvcla/article/details/45585315

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!