codeforces Good Bye 2014

畫船聽雨發表於2015-01-01

Good Bye 2014

2014年最後一場CF,沒打好,有點慘淡。。。。 

http://codeforces.com/contest/500

A:簡單模擬一下過程就有可以了。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define mod 1000000007



const int maxn = 2000010;

using  namespace std;

int vis[maxn];
int num[maxn];

int main()
{
    int n, t;
    while(cin >>n>>t)
    {
        for(int i = 1; i < n; i++)
        {
            scanf("%d",&num[i]);
        }
        int x = 1;
        int flag = 0;
        while(1)
        {
            if(x > t) break;
            if(x == t)
            {
                flag = 1;
                break;
            }
            x += num[x];
        }
        if(flag) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

B:你要保證所有可以相會到達的“團”中的數字按照從大到小的順序排列,需要先dfs找到圖的連通“團”,然後和後面的可達的進行比較找出來最小的放在前面。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);

const int maxn = 310;

using namespace std;


char str[maxn][maxn];
int vis[maxn];

vector<int>g[maxn];
vector<int>G[maxn];

int num[maxn];
int mark[maxn];
void dfs1(int x, int fa)
{
    if(mark[x]) return;
    int n = g[x].size();
    if(!n) return;
    mark[x] = 1;
    for(int i = 0; i < n; i++)
    {
        if(fa == g[x][i]) continue;
        dfs1(g[x][i], x);
    }
}

int dfs(int x, int fa)
{
    if(vis[x]) return INF;
    int n = G[x].size();
    if(n == 0) return num[x];
    vis[x] = 1;
    int Min = num[x];
    for(int i = 0; i < n; i++)
    {
        if(G[x][i] == fa) continue;
        Min = min(Min, dfs(G[x][i], x));
    }
    return Min;
}

int main()
{
    int n;
    while(cin >>n)
    {
        for(int i = 1; i <= n; i++)
        {
            g[i].clear();
            G[i].clear();
        }
        for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
        for(int i = 1; i <= n; i++) scanf("%s",str[i]+1);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++) if(str[i][j] == '1') g[i].push_back(j);
        for(int i = 1; i <= n; i++)
        {
            memset(mark, 0, sizeof(mark));
            dfs1(i, -1);
            for(int j = 1; j <= n; j++)
            {
                if(i == j) continue;
                if(!mark[j]) continue;
                if(j < i) continue;
                G[i].push_back(j);
            }
        }
        for(int i = 1; i <= n; i++)
        {
            memset(vis, 0, sizeof(vis));
            ///for(int j = 1; j <= i-1; j++) vis[j] = 1;
            int x = dfs(i, -1);
            int pos;
            for(int j = 1; j <= n; j++)
            {
                if(num[j] == x)
                {
                    pos = j;
                    break;
                }
            }
            swap(num[i], num[pos]);
        }
        for(int i = 1; i <= n; i++) cout<<num[i]<<" ";
    }
}

C:瞎搞題,把陣列按照給出的順序模擬一下取書的過程就可以了啊。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define mod 1000000007



const int maxn = 3010;

using  namespace std;


int num[maxn];
int f[maxn];
int p[maxn];
int fx[maxn];
int vis[maxn];
int xp[maxn];

int main()
{
    int n, m;
    while(cin >>n>>m)
    {
        for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
        for(int i = 1; i <= m; i++) scanf("%d",&f[i]);
        int ans = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= m; i++)
        {
            if(vis[f[i]]) continue;
            fx[ans++] = f[i];
            vis[f[i]] = 1;
        }

        int sum = 0;
        for(int i = 1; i <= m; i++)
        {
            int cnt = 0;
            int pos = 0;
            int ip;
            memset(vis, 0, sizeof(vis));
            for(int j = 0; j < ans; j++)
            {
                if(fx[j] != f[i])
                {
                    cnt += num[fx[j]];
                }
                else
                {
                    vis[j] = 1;
                    ip = j;
                    break;
                }
            }
            sum += cnt;
            if(vis[0]) continue;
            xp[0] = fx[ip];
            for(int k = 0; k < ip; k++)
                xp[k+1] = fx[k];
            for(int k = ip+1; k < ans; k++)
                xp[k] = fx[k];
            for(int k = 0; k < ans; k++) fx[k] = xp[k];
        }
        cout<<sum<<endl;
    }
    return 0;
}

D:大體意思就是:給你一個無向圖讓你任意改變一些邊的權值,然後求出改變之後的期望。

E = p*w。

p = 這條邊對應的個數x/sum,sum = 所有的選擇的情況C(n,3)。由於每條邊會被走兩次(任取三條邊畫一下就可以發現)所以最後結果要*2。

需要dfs+列舉邊求出任意兩點之間邊權的總和。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);

const int maxn = 200010;

using namespace std;


int deep[maxn];
double num[maxn];
///double sum[maxn];
double w[maxn];
double xsum[maxn];
int vis[maxn];
double p[maxn];

vector<int>g[maxn];

struct node
{
    int x, y;
} f[maxn];


double dfs(int x, double d)
{
    if(vis[x]) return 0;
    int n = g[x].size();
    deep[x] = d+1;
    vis[x] = 1;
    num[x]++;
    for(int i = 0; i < n; i++)
    {
        if(vis[g[x][i]]) continue;
        num[x] += dfs(g[x][i], d+1);
    }
    return num[x];
}

int main()
{
    int n;
    while(cin >>n)
    {
        for(int i = 1; i < n; i++)
        {
            scanf("%d %d %lf",&f[i].x, &f[i].y, &w[i]);
            g[f[i].x].push_back(f[i].y);
            g[f[i].y].push_back(f[i].x);
        }
        memset(vis, 0, sizeof(vis));
        memset(num, 0, sizeof(num));
        dfs(1, 0);
        double ans = 0.0;
        double sx = 1.0*n*(n-1.0)*(n-2.0)/6.0;
        for(int i = 1; i <= n-1; i++)
        {
            int x = f[i].x;
            int y = f[i].y;
            int deep1 = deep[x];
            int deep2 = deep[y];
            double sum1 = 0;
            double sum2 = 0;
            if(deep1 >= deep2)
            {
                sum1 = n*1.0-num[x];
                sum2 = num[x];
            }
            else
            {
                sum2 = n*1.0-num[y];
                sum1 = num[y];
            }
            xsum[i] = 0;
            xsum[i] += (sum1-1)*sum1/2*sum2;
            xsum[i] += (sum2-1)*sum2/2*sum1;
            p[i] = xsum[i]*1.0/sx;
            ans += p[i]*w[i];
        }
        int m;
        cin >>m;
        int x;
        double y;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d %lf",&x, &y);
            ans -= (p[x]*(w[x]-y));
            w[x] = y;
            printf("%.6lf\n",ans*2.0);
        }
    }
    return 0;
}


相關文章