华中农业大学第五届程序设计大赛网络同步赛

Problem A: Little Red Riding Hood

Description
Once upon a time, there was a little girl. Her name was Little Red Riding Hood. One day, her grandma was ill. Little Red Riding Hood went to visit her. On the way, she met a big wolf. “That’s a good idea.”,the big wolf thought. And he said to the Little Red Riding Hood, “Little Red Riding Hood, the flowers are so beautiful. Why not pick some to your grandma?” “Why didn’t I think of that? Thank you.” Little Red Riding Hood said.
Then Little Red Riding Hood went to the grove to pick flowers. There were n flowers, each flower had a beauty degree a[i]. These flowers arrayed one by one in a row. The magic was that after Little Red Riding Hood pick a flower, the flowers which were exactly or less than d distances to it are quickly wither and fall, in other words, the beauty degrees of those flowers changed to zero. Little Red Riding Hood was very smart, and soon she took the most beautiful flowers to her grandma’s house, although she didn’t know the big wolf was waiting for her. Do you know the sum of beauty degrees of those flowers which Little Red Riding Hood pick?
Input
The first line input a positive integer T (1≤T≤100), indicates the number of test cases. Next, each test case occupies two lines. The first line of them input two positive integer n and
k (2 <= n <= 10^5 ) ,1 <= k <= n ), the second line of them input n positive integers a (1<=a <=10^5)
Output
Each group of outputs occupies one line and there are one number indicates the sum of the largest beauty degrees of flowers Little Red Riding Hood can pick.

Sample Input
1
3 1
2 1 3
Sample Output
5

题意:在一个序列中选取若干个数字,数字之间间隔的数字个数不能低于k,要求能取的最大值。

设f[i]表示到i为止,并且i位置必取的最大值。
f[i] = max(f[j]) + a[i]; j<=i-d-1;

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

int f[111111];
int a[111111];

int main(){
    int T,n,d;
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&d);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(f,0,sizeof(f));
        int mx = a[1];
        for(int i=1;i<=d+1;i++){
            f[i]=a[i];
        }

        for(int i=1;i+d+1<=n;i++){
            if(f[i]>mx) mx=f[i];
            f[i+d+1]=mx+a[i+d+1];
        }
        int ans = f[1];
        for(int i=1;i<=n;i++)
            if(f[i]>ans) ans = f[i];
        printf("%d\n",ans);
    }
    return 0;
} 

Problem D: GCD

Description

Input
The first line is an positive integer T . (1<=T<= 10^3) indicates the number of test cases. In the next T lines, there are three positive integer n, m, p (1<= n,m,p<=10^9) at each line.

Output

Sample Input
1
1 2 3

Sample Output
1

f1+f2+...+fn=fn+21

于是,

1+Sn=fn+2


gcd(fn,fm)=fgcd(n,m)

于是

#include<cstdio> 
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=13;
ll n,m,a,b,P;

ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}

struct matrix{
    ll a[N][N];
    int row,col;
    matrix():row(N),col(N){memset(a,0,sizeof(a));}
    matrix(int x,int y):row(x),col(y){memset(a,0,sizeof(a));}
    ll* operator [] (int x){return a[x];}
    matrix operator * (matrix x){
        matrix tmp ;
        for (int i=0;i<=n+1;i++)
            for (int j=0;j<=n+1;j++){
                tmp[i][j]=0;
                for (int k=0;k<=n+1;k++)
                    tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%P;
            }
        return tmp;
    }   
    void operator *= (matrix x){*this = *this * x;}
    matrix operator ^ (ll x){
        matrix ret;
        for (int i=0;i<=n+1;i++)ret[i][i]=1;
        matrix tmp = *this;
        for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;}
        return ret;
    }
    void print(){
        for (int i=0;i<=n+1;i++){
            for (int j=0;j<=n+1;j++)
                printf("%d ",a[i][j]);
            puts("");
        }
    }
};

int main(){
    int T;
    cin>>T;
    while(T--){
        n=2;
        cin>>a>>b>>P;
        a+=2;b+=2;
        matrix tmp;
        tmp[0][0]=tmp[0][1]=tmp[1][0]=1;
        tmp[1][1]=0;
        tmp = tmp^(gcd(a,b));
        cout<<tmp[1][0]<<endl;
    }

    return 0;
}

Problem G: Sequence Number

Description
In Linear algebra, we have learned the definition of inversion number:

Assuming A is a ordered set with n numbers ( n > 1 ) which are different from each other. If exist positive integers i , j, ( 1 ≤ i < j ≤ n and A[i] > A[j]), <A[i], A[j]> is regarded as one of A’s inversions. The number of inversions is regarded as inversion number. Such as, inversions of array <2,3,8,6,1> are <2,1>, <3,1>, <8,1>, <8,6>, <6,1>,and the inversion number is 5.

 Similarly, we define a new notion —— sequence number, If exist positive integers i, j, ( 1 ≤ i ≤ j ≤ n and A[i]  <=  A[j], <A[i], A[j]> is regarded as one of A’s sequence pair. The number of sequence pairs is regarded as sequence number. Define j – i as the length of the sequence pair.

 Now, we wonder that the largest length S of all sequence pairs for a given array A. 

Input
There are multiply test cases.

In each case, the first line is a number N(1<=N<=50000 ), indicates the size of the array, the 2th ~n+1th line are one number per line, indicates the element Ai (1<=Ai<=10^9) of the array.  

Output
Output the answer S in one line for each case.

Sample Input
5
2 3 8 6 1
Sample Output
3

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

long long a[50005];

int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)
            scanf("%lld",a+i);
        int mx = 0;
        for(int i=2;i<=n;i++){
            for(int j=1;j<i;j++)
                if(a[i]>a[j]){
                    if(mx<i-j)
                        mx = i-j;
                    break;
                }
        }
        printf("%d\n",mx);
    }
    return 0;
} 

Problem J: Color Circle

Description
There are colorful flowers in the parterre in front of the door of college and form many beautiful patterns. Now, you want to find a circle consist of flowers with same color. What should be done ?

 Assuming the flowers arranged as matrix in parterre, indicated by a N*M matrix. Every point in the matrix indicates the color of a flower. We use the same uppercase letter to represent the same kind of color. We think a sequence of points d1, d2, … dk makes up a circle while:

1. Every point is different.

2. k >= 4

3. All points belong to the same color.

4. For 1 <= i <= k-1, di is adjacent to di+1 and dk is adjacent to d1. ( Point x is adjacent to Point y while they have the common edge).

N, M <= 50. Judge if there is a circle in the given matrix. 

Input
There are multiply test cases.

 In each case, the first line are two integers n and m, the 2nd ~ n+1th lines is the given n*m matrix. Input m characters in per line. 

Output
Output your answer as “Yes” or ”No” in one line for each case.

Sample Input
3 3
AAA
ABA
AAA
Sample Output
Yes

dfs。。。。

别用getchar()

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int n,m;

char mp[55][55];
bool  v[55][55];
bool ans;

const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};

void dfs(int x,int y,int edx,int edy,int dep){
    if(ans) return;
    for(int c=0;c<4;c++){
        int nowx = x + dx[c];
        int nowy = y + dy[c];
        if(nowx<1||nowx>n) continue;
        if(nowy<1||nowy>m) continue;
        if(mp[nowx][nowy]!=mp[x][y]) continue;
        if(nowx==edx && nowy==edy && dep >= 4){
            ans=1;
            return;
        }
        if(v[nowx][nowy]) continue;
        v[nowx][nowy]=1;
        dfs(nowx,nowy,edx,edy,dep+1);
    }
}

int main(){
    while(cin>>n>>m){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>mp[i][j];
        ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                memset(v,0,sizeof(v));
                v[i][j]=1;
                dfs(i,j,i,j,1);
                if(ans) break;
            }
            if(ans) break;
        }
        puts(ans?"Yes":"No");
    }
    return 0;
} 

Problem K: Deadline

Description
There are N bugs to be repaired and some engineers whose abilities are roughly equal. And an engineer can repair a bug per day. Each bug has a deadline A[i].

  Question: How many engineers can repair all bugs before those deadlines at least?

  1<=n<= 1e6. 1<=a[i] <=1e9 

Input
There are multiply test cases.

   In each case, the first line is an integer N , indicates the number of bugs. The next line is n integers indicates the deadlines of those bugs. 

Output
There are one number indicates the answer to the question in a line for each case.

Sample Input
4
1 2 3 4
Sample Output
1

一开始一直sort之类的一直超时,没搞明白,发现别人做的时候不考虑 a[i]>n的了。

a[i]>=n的数根本没有必要,一个程序员总是够的,所以遍历,标记小于n的就是;

这题只要想到思路还是很简单的,假设所有工程师每天都在修复bug,那么对天数记录bug的前缀和,O(n)得到答案max(pre[i]+i-1)/i)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int a[1111111],n;

int read(){  
    int x=0; char ch=getchar();  
    while (ch<'0' || ch>'9') ch=getchar();  
    while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }  
    return x; 
}

int pre[1111111];

int main(){
    while(~scanf("%d",&n)){
        memset(pre,0,sizeof(pre));
        for(int i=1;i<=n;i++){
            a[i]=read();
            if(a[i]>1000005) continue;
            pre[a[i]]++;
        }
        for(int i=1;i<=1000000;i++)
            pre[i] += pre[i-1];
        int mx=1;
        for(int i=1;i<=1000000;i++)
            mx = max(mx,pre[i]/i+(pre[i]%i?1:0));
        cout<<mx<<endl; 
    }
    return 0;
} 

Problem L: Happiness

求字符串中AB出现的次数

#include<cstdio>
#include<cstring>
using namespace std;

char ch[1000000];

int main(){
    int n;
    scanf("%d",&n);
    int T=0;
    while (n--){
        T++;
        scanf("%s",ch);
        long long len=0,ans=0,length=strlen(ch);
        for (long long i=0;i<length-1;i++)
          if (ch[i]=='A'&&ch[i+1]=='B') ans++;
        printf("Case #%d:\n",T);
        printf("%lld\n",ans);
    }
    return 0; 
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值