USACO2019-Jan Silver

USACO2019-Jan Silver

难度约为提高组Day1.

1. Grass Planting

题目描述

到了一年中Farmer John在他的草地里种草的时间了。整个农场由 N N N 块草地组成 ( 1 ≤ N ≤ 1 0 5 ) (1 \le N \le 10^5) (1N105),方便起见编号为 1 … N 1 \ldots N 1N,由条双向的小路连接,每块草地都可以经过一些小路到达其他所有的草地。

Farmer John当然可以在每块草地里种不同种类的草,但是他想要使得使用的草的种类数最小,因为他用的草的种类数越多,他就需要负担更高的花费。

不幸的是,他的奶牛们对选择农场上的草表现得十分苛刻。如果两块相邻(由一条小路直接相连)的草地种了同一种草,或者即使是两块接近相邻(均可由一条小路直接连向同一块草地)的草地,那么奶牛们就会抱怨她们进餐的选择不够多样。Farmer John能做的只能是抱怨这些奶牛,因为他知道她们不能被满足的时候会制造多大的麻烦。

请帮助Farmer John求出他的整个农场所需要的最少的草的种类数。

输入输出

输入的第一行包含 N N N。以下 N − 1 N−1 N1 行每行描述了一条小路连接的两块草地;输出Farmer John需要使用的最少的草的种类数。

样例输入

4
1 2
4 3
2 3

样例输出

3

解释与说明

在这个简单的例子中, 4 4 4 块草地以一条直线的形式相连。最少需要三种草。例如,Farmer John可以用草 A , B A,B A,B C C C 将草地按 A − B − C − A A - B - C - A ABCA 的方式播种。

2. Icy Perimeter

题目描述

Farmer John要开始他的冰激凌生意了!他制造了一台可以生产冰激凌球的机器,然而不幸的是形状不太规则,所以他现在希望优化一下这台机器,使其产出的冰激凌球的形状更加合理。

机器生产出的冰激凌的形状可以用一个 N × N N \times N N×N ( 1 ≤ N ≤ 1000 ) (1≤N≤1000) (1N1000) 的矩形图案表示,例如:

##....
....#.
.#..#.
.#####
...###
....##

每个’.‘字符表示空的区域,每个’#'字符表示一块1×1的正方形格子大小的冰激凌。

不幸的是,机器当前工作得并不是很正常,可能会生产出多个互不相连的冰激凌球(上图中有两个)。一个冰激凌球是连通的,如果其中每个冰激凌的正方形格子都可以从这个冰激凌球中其他所有的冰激凌格子出发重复地前往东、南、西、北四个方向上相邻的冰激凌格子所到达。

Farmer John想要求出他的面积最大的冰激凌球的面积和周长。冰激凌球的面积就是这个冰激凌球中’#'的数量。如果有多个冰激凌球并列面积最大,他想要知道其中周长最小的冰激凌球的周长。在上图中,小的冰激凌球的面积为 2 2 2,周长为 6 6 6,大的冰激凌球的面积为 13 13 13,周长为 22 22 22

注意一个冰激凌球可能在中间有“洞”(由冰激凌包围着的空的区域)。如果这样,洞的边界同样计入冰激凌球的周长。冰激凌球也可能出现在被其他冰激凌球包围的区域内,在这种情况下它们计为不同的冰激凌球。例如,以下这种情况包括一个面积为 1 1 1 的冰激凌球,被包围在一个面积为 16 16 16 的冰激凌球内:

#####
#...#
#.#.#
#...#
#####

同时求得冰激凌球的面积和周长十分重要,因为Farmer John最终想要最小化周长与面积的比值,他称这是他的冰激凌的“冰周率”。当这个比率较小的时候,冰激凌化得比较慢,因为此时冰激凌单位质量的表面积较小。

输入输出

输入的第一行包含 N N N,以下 N N N 行描述了机器的生产结果。其中至少出现一个’#'字符。

输出一行,包含两个空格分隔的整数,第一个数为最大的冰激凌球的面积,第二个数为它的周长。如果多个冰激凌球并列面积最大,输出其中周长最小的那一个的信息。

样例输入

6
##....
....#.
.#..#.
.#####
...###
....##

样例输出

13 22

3. Mountain View

题目描述

从农场里奶牛Bessie的牧草地向远端眺望,可以看到巍峨壮丽的山脉绵延在地平线上。山脉里由 N N N 座山峰 ( 1 ≤ N ≤ 1 0 5 ) (1≤N≤10^5) (1N105)。如果我们把Bessie的视野想象成 x y xy xy 平面,那么每座山峰都是一个底边在 x x x 轴上的三角形。山峰的两腰均与底边成 45 45 45 度角,所以山峰的峰顶是一个直角。于是山峰i可以由它的峰顶坐标 ( x i , y i ) (x_i,y_i) (xi,yi) 精确描述。没有两座山峰有完全相同的峰顶坐标。

Bessie尝试数清所有的山峰,然而由于它们几乎是相同的颜色,所以如果一座山峰的峰顶在另一座山峰的三角形区域的边界上或是内部,她就无法看清。

请求出Bessie能够看见的不同的山峰的峰顶的数量,也就是山峰的数量。

输入输出

输入的第一行包含 N N N。以下 N N N 行每行包含 x i   ( 0 ≤ x i ≤ 1 0 9 ) x_i \ (0≤x_i≤10^9) xi (0xi109) y i   ( 1 ≤ y i ≤ 1 0 9 ) y_i \ (1≤y_i≤10^9) yi (1yi109),描述一座山峰的峰顶的坐标;输出Bessie能够分辨出的山峰的数量。

样例输入

3
4 6
7 2
2 5

样例输出

2

题解

  1. 3 3 3 道题的难度:普及 / / /提高 − - ,提高 + / + / +/省选 − - ,普及 + / + / +/提高

  2. T 1 T1 T1 题意说白了就是让一个节点和它的祖先、儿子节点的颜色互不相同。那最少的颜色数就是最大的度数加上 1 1 1

  3. T 2 T2 T2 的话求最大的面积用 B F S BFS BFS 扫一遍就行了,求周长就是在求面积的基础上,往四个方向搜索。如果碰到了边界或者 .,就可以把边长加 1 1 1。具体的实现可以看下面的代码。

  4. T 3 T3 T3 T 2 T2 T2 简单,一个简单的模拟加数学推导就做完了。

  5. 代码:

    //T1. Grass Planting
    #include 
    using namespace std;
    
    int n, m, ans=0, d[300000];
    
    int cmp(int x,int y) {return x>y;}
    
    inline int read()
    {
        int re=0, f=1; char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0' && ch<='9') {re=re*10+(ch-'0'); ch=getchar();}
        return re*f;
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=n-1;++i)
        {
            int x=read(), y=read();
            d[x]++, d[y]++;
        }
        sort(d+1,d+n+1,cmp);
        printf("%d\n",d[1]+1);
        return 0;
    }
    
    
    //T2. Icy Perimeter
    #include 
    #define M 1001
    using namespace std;
    
    int n, m, maxS=0, MaxC=0;
    char a[M][M];
    struct Node{
        int s, c;
    }ans[1000001];
    
    int cmp(Node x,Node y)
    {
        if(x.s!=y.s) return x.s>y.s;
        else return x.c<y.c;
    }
    
    void init()
    {
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j)
            cin>>a[i][j];
    }
    
    void Bfs(int i,int j,int k)
    {
        ans[k].s++;
        a[i][j]='o';
        if(i-1<1) ans[k].c++; if(i+1>n) ans[k].c++; if(j-1<1) ans[k].c++; if(j+1>n) ans[k].c++;
        if(a[i+1][j]=='.' && i+1<=n) ans[k].c++;
        if(a[i-1][j]=='.' && i-1>=1) ans[k].c++;
        if(a[i][j-1]=='.' && j-1>=1) ans[k].c++;
        if(a[i][j+1]=='.' && j+1<=n) ans[k].c++;
    
        if(i-1>=1 && a[i-1][j]=='#') Bfs(i-1,j,k); 
        if(i+1<=n && a[i+1][j]=='#') Bfs(i+1,j,k); 
        if(j-1>=1 && a[i][j-1]=='#') Bfs(i,j-1,k); 
        if(j+1<=n && a[i][j+1]=='#') Bfs(i,j+1,k);
    }
    
    int main()
    {
        scanf("%d",&n);
        init();
        int k=0;
        for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=n;++j)
            {
                if(a[i][j]=='#') 
                {
                    k++;
                    Bfs(i,j,k);
                }
            }
        }
        sort(ans+1,ans+k+1,cmp);
        printf("%d %d\n",ans[1].s,ans[1].c);
        return 0;
    }
    
    
    //T3. Mountain View
    #include 
    using namespace std;
    const int maxd = 1e5+10;
    int n;
    struct node{
        int x,y;
    }a[maxd];
    inline int cmp(node p,node q){
        if(p.x==q.x) return p.y>q.y;
        return p.x<q.x;
    }
    int main(){
        ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
        cin>>n;
        for(register int i=1,x,y;i<=n;++i)cin>>x>>y,a[i].x=x-y,a[i].y=x+y;
        sort(a+1,a+1+n,cmp);register int t=0,res=0;
        for(register int i=1;i<=n;++i){
            if(a[i].y>t)++res,t=a[i].y;
        }
        cout<<res;
        return 0;
    }
    

你可能感兴趣的:(模拟赛)