1. 程式人生 > >華中農業大學第五屆程式設計大賽網路同步賽

華中農業大學第五屆程式設計大賽網路同步賽

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; 
}