Codeforces Round #328 (Div. 2)

A. PawnChess

很简单的暴力。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<deque>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const double eps=1e-10;
const int INF=1000000000;
const int maxn=1000000+10;

char mp[10][10];

int main()
{
    //freopen("in2.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    for(int i=0;i<8;i++)
    {
        scanf("%s",mp[i]);
    }
    int sa=INF,sb=INF;
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            if(mp[i][j]=='W')
            {
                int st=0;
                bool can=1;
                for(int k=i-1;k>=0;k--)
                {
                    if(mp[k][j]=='.')
                    {
                        st++;
                    }
                    else
                    {
                        can=0;
                        break;
                    }
                }
                if(can==1)
                {
                    sa=min(sa,st);
                }
            }
            else if(mp[i][j]=='B')
            {
                int st=0;
                bool can=1;
                for(int k=i+1;k<8;k++)
                {
                    if(mp[k][j]=='.')
                    {
                        st++;
                    }
                    else
                    {
                        can=0;break;
                    }
                }
                if(can==1)
                {
                    sb=min(sb,st);
                }
            }
        }
    }
    if(sa>sb) cout<<'B'<<endl;
    else cout<<'A'<<endl;
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
View Code

B. The Monster and the Squirrel

就是个找规律而已,输入n,输出(n-2)*(n-2)。注意要用long long。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<deque>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const double eps=1e-10;
const int INF=1000000000;
const int maxn=1000000+10;



int main()
{
    //freopen("in2.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    LL n;
    cin>>n;
    cout<<(n-2)*(n-2)<<endl;
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
View Code

C. The Big Race

题目描述太烂,读了半天都不懂。。不做了。。

D. Super M(虚树,找直径)

1.第一次肯定要落在被攻击的点上。因为如果落在无关点上,那么肯定要先从无关点上走到一个攻击点上,那么这段路没有意义啊,完全可以直接落在那个攻击点上。

2.无关的点能不走就不走,所以最后走过的肯定就是一棵包含所有攻击点的最小子树。

3.从一个攻击点出发,最后再回来。总路程是子树的边长之和的2倍。但是实际上到了最后一个攻击点后就没有必要再走回来了,所以最后总路程是sum-mx,但是要使总路程最短,就要让mx(也就是终点到起点的路径长)最长,那么显然是这个虚树的直径最长。

所以本题就是,找出这个虚树,再求出虚树直径。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<deque>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const double eps=1e-10;
const int INF=1000000000;
const int maxn=1000000+10;
const int MAX = 130000;
vector<int> adj[MAX];
int d[MAX], size[MAX];
bool mark[MAX];
void dfs(int p, int v)
{
    size[v] = 0;
    if (mark[v])
        size[v] = 1;
    for (int i = 0; i < adj[v].size(); i++)
    {
        int u = adj[v][i];
        if (u != p)
        {
            d[u] = d[v] + 1;
            dfs(v, u);
            size[v] += size[u];//size是子树里有多少mark节点(包括自己)
        }
    }
}
int main()
{
    //freopen("in2.txt","r",stdin);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n - 1; i++)
    {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 0; i < m; i++)
    {
        int v;
        cin >> v;
        v--;
        mark[v] = true;
    }
    dfs(-1, 0);
    int v = -1;
    for (int i = 0; i < n; i++)
        if (mark[i] && (v == -1 || d[v] < d[i]))
            v = i;
    memset(d, 0, sizeof(d));
    dfs(-1, v);
    int sum = 0;
    int mx = 0;
    for (int i = 0; i < n; i++)
    {
        if (size[i] > 0 && m - size[i] > 0)//m==size[i]的那个不用加了,因为边比点少一个。
            sum += 2;
        cout<<i<<' '<<size[i]<<endl;
        if (mark[i])
            mx = max(mx, d[i]);
    }
    for (int i = 0; i < n; i++)//找出字典序小的那个作为登陆点
        if (mark[i] && i < v && d[i] == mx)
        {
            v = i;
            break;
        }
    cout << v + 1 << "\n" << sum - mx << "\n";
    return 0;
}
View Code

 

posted @ 2015-11-04 21:18  周洋  阅读(233)  评论(0编辑  收藏  举报