ZJNU-2020-12-05 组队赛

A-Shik and Stone

题意:

给了一个n,m的矩阵,给出从左上到右下的路径,用#表示,这个路径是由上下左右四个方向都可以行走,现在问只向右和下行走能否完全覆盖给定的路径。

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
int n,m;
char tu[10][10];
int vis[10][10];
int main()
{
   
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        cin>>tu[i];
    bool flag=true;
    int r=0;
    for(int i=0;i<n;i++)
    {
   
        while(r<m&&tu[i][r]=='#')
        {
   
            vis[i][r]=1;
            r++;
        }
        r--;
    }
    for(int i=0;i<n;i++)
    {
   
        for(int j=0;j<m;j++)
        {
   
            if(tu[i][j]=='#'&&vis[i][j]==0)flag=false;
        }
    }
    if(flag)printf("Possible");
    else printf("Impossible");
    return 0;
}


B-Construct Sequences

题意:

给定一个数组 x ,里面的整数用于下标,代表 a x i + b x i a_{x_i}+b_{x_i} axi+bxi并且 a x i + b x i < a x i + 1 + b x i + 1 a_{x_i}+b_{x_i}<a_{x_{i+1}}+b_{x_{i+1}} axi+bxi<axi+1+bxi+1,要求构造a数组和b数组,a数组是从小到大有序,b数组是从大到小有序

solution:

先将a和b分别构造成如下
a:1,1+n,1+2n,1+3n…
b:1+(n-1)n,1+(n-2)n,1+(n-3)n…
这样构造能保证a,b数组加上一个小于n的数后,其有序性不变。
此时对应下标的 a i + b i a_i+b_i ai+bi相等,之后根据给定的数组顺序,分别对对应下标的a数组或b数组进行对应的加0,1,2,3,…操作

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
int n;
int x[20005],a[20005],b[20005];
int main()
{
   
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
   
        scanf("%d",&x[i]);
        a[i]=1+i*n;
        b[i]=1+(n-i-1)*n;
    }
    for(int i=0;i<n;i++)
        a[x[i]-1]+=i;
    for(int i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    for(int i=0;i<n;i++)
        printf("%d ",b[i]);
    return 0;
}

C-Pushing Balls

D-Shik and Game

E-Shik and Travel

F-Shik and Copying String

G-AtCoDeer and Rock-Paper

题意:

给了对手的石头、布手势,g-石头,p-布,按照石头-剪刀-布规则判断输赢,赢得1分,输失1分,平局双方得0分,问最多能获得多少分,要求自己出石头的次数大于等于布。

solution:

p-p平局,p-g输,g-p赢,所以只要统计g的个数,如果g大于等于一半,那么两者相减的就是赢的次数,否则就是输的次数。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
string s;
int main()
{
   
    cin>>s;
    int res=0;
    for(int i=0;i<s.length();i++)
    {
   
        if(s[i]=='g')
            res++;
    }
    res-=(s.length()+1)/2;
    cout<<res;
    return 0;
}

H-Building Cubes with AtCoDeer

I-Painting Graphs with AtCoDeer

J-An Invisible Hand

题意:

给了n个小镇,以及其中卖出和买进苹果的价钱,卖出等于买进。每次在一个镇上只能买或卖一个苹果,只能由第i的镇移到第i+1的镇,问至少修改数组几次,使卖苹果的最大利润至少减少1.

solution:

按顺序求出后面n-i个镇的最大值和第i的镇的差最大为多少,这个就是最大利润。然后修改利润差等于最大值的城镇一次。

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
int n,k;
int a[100005],b[100005];
int main()
{
   
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int maxn=0;
    for(int i=n;i>1;i--)
    {
   
        b[i]=max(b[i+1],a[i]);
        maxn=max(b[i]-a[i-1],maxn);
    }
    int cnt=0;
    for(int i=1;i<n;i++)
        if(b[i+1]-a[i]==maxn)cnt++;
    printf("%d",cnt);
    return 0;
}

K-Integers on a Tree

L-Snuke’s Coloring 2