2018 黑龍江省大學生程序設計競賽


A Count Task

題面:

Count is one of WNJXYK’s favorite tasks. Recently, he had a very long string and he wondered that how many substrings which contains exactly one kind of lowercase in this long string. But this string is so long that he had kept counting for several days. His friend Kayaking wants to help him, so he turns to you for help.

InputThe input starts with one line contains exactly one positive integer $T$ which is the number of test cases.
Each test case contains one line with a string which you need to do a counting task on.OutputFor each test case, output one line containing “y” where y is the number of target substrings.Sample Input

3
qwertyuiop
qqwweerrttyyuuiioopp
aaaaaaaaaa

Sample Output

10
30
55

Hint

1<=T<=20,1<=len(string)<=10^5,1<=∑len(string)<=10^5
Strings only contain lowercase English letters.

題解:

計算每個單詞的對相同的單詞段的貢獻度,然后累和。

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
ll n,m,t,k,ans,cnt;
int a[mxn] , b[mxn] , c[2*mxn] , d[mxn] , vis[mxn];
void solve() 
{
    string str ;
    for(cin>>t;t;t--){
        cin>>str;
        ans = 0 ;
        for(int i=0;i<str.size();i++){
            k = 1;
            while(str[i]==str[i+1] && i<str.size())
                k++ , i++ ;
            ans+=(1+k)*k/2;
        }
        cout<<ans<<endl;
    }    
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

A Sequence Game

題面:

 

One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solutions for a couple of days. And then he had a surprise that he misunderstood that problem and easily figured out a solution using segment tree. Now he still wonders that solution for the misread problem.
There is a sequence with  NN positive integers A1A1,A2A2,...,AnAn and MM queries. Each query will give you an interval [L,R] and require an answer with YES/NO indicates that whether the numbers in this interval are continuous in its integer range.
Let us assume that the maximal number in an interval is mxmx and the minimal number is mimi. The numbers in this interval are continuous in its integer range means that each number from mimi to mxmx appears at least once in this interval.

InputThe input starts with one line contains exactly one positive integer TT which is the number of test cases. And then there are T cases follow.
The first line contains two positive integers nn,mm which has been explained above.The second line contains positive integers A1A1,A2A2,...,AnAn.
Then there will be m lines followed. Each line contains to positive numbers LiLi,RiRi indicating that the ith query’s interval is [LiLi,RiRi].
OutputFor each test case, output m line.
Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.Sample Input

2
3 3
3 1 2 
2 3
1 3
1 2
5 3
1 2 2 4 5 
1 5
1 3
3 3

Sample Output

YES YES NO NO YES YES

Hint

T=5
1<=n<=100000
1<=Ai<=10^9
1<=m<=100000
The input file is very large, so you are recommend to use scanf() and printf() for IO.

 題解:

莫隊的學習

#include <bits/stdc++.h>
const int mxn = 1e5+7 ;
using namespace std;
typedef long long ll;
 
int t,n,m,block,lg[mxn],a[mxn],b[mxn],mx[mxn][35],mn[mxn][35],cur=0,cnt[mxn];
bool ans[mxn];
struct node{
    int l,r,id;
    friend bool operator < (node x,node y) {
        return x.l/block==y.l/block?x.r<y.r:x.l/block<y.l/block;
    }
}q[mxn];
template <class T>
void rd(T &x){
    x=0;T f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') f = -1 ; c = getchar();}
    while(isdigit(c)) {x = (x<<1) + (x<<3) + (c^48);c = getchar();}
    x*=f;
}
void LOG(){lg[0]=-1;for(int i=1;i<mxn;i++) lg[i]=lg[i>>1]+1;}
void ST(){
    for(int i=1;i<=n;i++) mx[i][0]=a[i] , mn[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++){
        for(int i=1;i+(1<<j)-1<=n;i++){
            mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
            mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
        }
    }
}
void add(int x){if(++cnt[x]==1) cur++;}
void del(int x){if(--cnt[x]==0) cur--;}
void rmq(int l,int r,int x)
{
    int k=lg[r+1-l];
    int mr = max(mx[l][k],mx[r+1-(1<<k)][k]);
    int ml = min(mn[l][k],mn[r+1-(1<<k)][k]);
    if(mr+1-ml==cur) ans[x] = true;
    else ans[x] = false;
}
int main()
{
    LOG(); rd(t);
    while(t--){
        rd(n) , rd(m) ; block=sqrt(n) ;
        for(int i=1;i<=n;i++)
            rd(a[i]) ,  b[i]=a[i];
        ST();
        sort(b+1,b+1+n);
        int all=unique(b+1,b+1+n)-(b+1);
        for(int i=1;i<=n;i++) 
            a[i]=lower_bound(b+1,b+1+all,a[i])-b;
        for(int i=1;i<=m;i++)
            rd(q[i].l),rd(q[i].r),q[i].id=i;
        sort(q+1,q+1+m);
        int l=1,r=0; cur=0;
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=m;i++){ ///莫隊入門
            while(l<q[i].l) del(a[l++]);
            while(l>q[i].l) add(a[--l]);
            while(r<q[i].r) add(a[++r]);
            while(r>q[i].r) del(a[r--]);
            rmq(l,r,q[i].id);
        }
        for(int i=1;i<=m;i++){
            if(ans[i]) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}
神奇的莫隊

 

A Hard Allocation

題面:

One day, WNJXYK came out an excellent idea that he could give his friends his special cakes which made of kiwis to eat in parties. But the process of making this kind of special cakes is very complex. One day, his friend Kayaking gave him a formulation which allows WNJXYK to produce one special cake with exact one kiwi in no time. Now let us have a big party over anyone’s imagination.
To simply this question we can assume that WNJXYK invited m friends to his house and he only had n kiwis this time. He wanted to produce special cakes with Kayaking’s formulation and give them to his friends.
Usually, it maybe not possible for people to get exactly same number of cakes in some situations. We can assume that people who received the most one get x cakes and people who received the least get y cakes. WNJXYK wondered that what is the minimal value of |x-y|?

InputThe input starts with one line contains exactly one positive integer T which is the number of test cases.
Each test case contains one line with exactly two positive integer n,m which has been explained above.OutputFor each test case, output one line containing “y” where y is the number of minimal difference.Sample Input

3
5 5
3 10
6 7

Sample Output

0
1
1

Hint

1<=T<=100,1<=n,m<=1000

題解:

比較N個人能否完整分配M個kiwis,如不能就1,反之就0

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
ll n,m,t,k,ans,cnt;
void solve() 
{
    string str ;
    for(cin>>t;t;t--){
        cin>>n>>m;
        if(n%m!=0) cout<<"1\n";
        else cout<<"0\n";
    }    
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

Similar Strings

題面:

Putting two similar strings together will create a very strong power that can quake the earth into parts and the person who did that can be called the Destroyer of the World. In order to stop the Destroyer of the World, WNJXYK decided to check every string in this world to make sure there is no pair of strings are similar. But some strings are too long that WNJXYK cannot judge whether they are similar to others, so he turns to you for help.
Now WNJXYK need you to determine the maximum s, for string A has a substring A’ and string B has a substring B’ whose length are both s and they differ on at most K positions.

InputThe input starts with one line contains exactly one positive integer T which is the number of test cases.
Each test case contains three lines. The first line contains an integer K and each of the following two lines contains a string indicates stringA or stringBOutputFor each test case, output one line containing “y” where y is the maximum s.Sample Input

3
3
qwertypoi
qwetyrio
0
qqqqq
qqqaqqqq
10
qwertyuiop
asdfghjklzxcvbnm

Sample Output

6
4
10

        
 

Hint

1<=T<=5,1<=len(A),len(B)<=4000,0<=K<=min{len(A),len(B)}
Strings only contain lowercase English letters.

題解:

題意是從兩個字符串中最長的一段字符串S,S中允許有K個位置的字符不相同,由於字符串的長度最大是4e3,暴力也不會T,就直接尺取長度,計算最值。

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
#define eps 1e-5 
#define open freopen("input.in","r",stdin);freopen("output.in","w",stdout);
int n,m,t,k,ans,cnt;

void calc(char *s1,char *s2)
{
    int l1 = strlen(s1) ;
    int l2 = strlen(s2) ;
    int l = 0 , r = -1 , cnt = 0 ;
    while(l<l1){
        while(cnt<=k && r<l1){
            r++;
            if(s1[r]!=s2[r]) cnt++;
        }
        ans = max(ans , r-l);
        if(s1[l]!=s2[l]) cnt--;
        l++;
    }
}
void solve() 
{
    char s1[mxn] , s2[mxn] ;
    for(cin>>t;t;t--){
        cin>>k>>s1>>s2; ans = 0 ;
        int l1 = strlen(s1) , l2 = strlen(s2);
        for(int i=0;i<l1;i++)
            calc(s1+i,s2);
        for(int i=0;i<l2;i++)
            calc(s2+i,s1);
        cout<<ans<<endl;
    }
}
int main()
{
    /// open
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

 

Flower

題面:

Rabbit loves flowers very much and she plants n pots of flowers in her house. But she never prunes them because she is lazy. So the flowers have different heights and look ugly. One day, Kayaking decides to prune the flowers to make them look beautiful. To make them have equal heights, smart Kayaking has a wonderful idea. Initially, the i-th pot of flower’s height is a[i]. Each time, Kayaking will select n-1 pots of flowers and prune them to make their height subtract 1 with his 49m knife. Exactly, the height of the flowers is at least 1. Now, Kayaking wants to know if it is possible to prune the flowers to make them have equal height. If possible, what is the minimum times he prunes the flowers. Could you tell him?
InputThe input starts with a line contains exactly one positive number T which is the number of test case. Each test case starts with a line contains a number n indicates the number of flowers. Then there is a line contains n numbers indicates a[i].OutputFor each test case, print a single line containing one integer—the minimum times Kayaking prunes the flowers, or -1 if it is impossible.
Sample Input
2
5
1 2 2 2 2
5
1 2 2 2 3
Sample Output
1
-1
Hint
T<=10,n<=10^5,ai<=10^9


題解:

每次選擇N-1個數減少一,逆向理解就是任意選擇一個數並加一,問經過數輪以后能否使得N個數全部一樣,那么,計算出逆向考慮需要的輪次為maxai  - a 1-n ,那么再正向考慮,輪次數如果小於maxai ,那么就可以認為,每次選擇N-1個數也可以將所有數變為同一個數

 

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
ll n,m,t,k,ans,cnt;
void solve() 
{
    for(cin>>t;t;t--){
        cin>>n;
        ans = 0 ; k = 0 ; cnt = -1 ;
        for(int i=1;i<=n;i++){
            cin>>k;
            ans += k ;
            cnt = max(cnt,k);
        }    
        if(n*cnt<cnt+ans)
            cout<<abs(ans-n*cnt)<<endl;
        else 
            cout<<-1<<endl;
    }    
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

 

Overflow

 題面:

Kayaking is a naughty boy and he loves to play water. One day, Kayaking finds a bucket. The bottom area of the bucket is S and the height is H. Initially, there is V volume water in the bucket. What makes Kayaking happy is that there are N cube woods beside the bucket. The side length of the i-th cube woods is L[i] and its density is P[i]. Kayaking wants to put all the cube woods to the bucket. And then he will put a cover at the top of the bucket. But CoffeeDog doesn’t allow unless Kayaking can tell CoffeeDog the height of the water in the bucket after Kayaking put all the cuboid woods to the bucket. Could you help him?
It is guaranteed that the cube woods aren’t overlapping. And after putting the wood to the bucket, the bottom of the wood is parallel to the bottom of the bucket.

InputThe first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N denoting the number of cube woods.
Then comes N line. Each line has two real numbers L[i] and P[i].
The last line contains three integers S, H and V.OutputFor each test cases, print a single line containing one real number—the height of the water in the bucket(the number should be rounded to the second digit after the decimal point).Sample Input

1
2
1 1.5
1 0.5
5 100 25

Sample Output

5.30

Hint

T<=10
n<=10^4,P<=6,L<=3,H<=100,L<=H
V,S<=10^7

題解:

在水足夠的時候,密度P>=1,則會沉於水面以下,排水體積等於物塊體積;密度P<1,則漂浮於水面上方,又因為有蓋子,所以可能會有排水的可能性。

在水不足的時候,密度P>=1,則會部分或全部沉於水面下,排水體積小於等於物塊體積,密度P<1,則漂浮於水面上,部分物塊可能會有排水體積

那么,就可以二分水面高度來計算。

注:題面里有講“全部放入”,所以不需要考慮疊放問題(憨憨的考慮了物塊的底面積於桶底面積的關系)

 

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
#define eps 1e-5 
#define open freopen("input.in","r",stdin);freopen("output.in","w",stdout);
int n,m,t,k,ans,cnt;
double l[mxn] , p[mxn] , s , h , v ;
bool check(double x)
{
    double sum = 0 ;
    for(int i=1;i<=n;i++){
        if(p[i]<1) sum+= p[i]*l[i]*l[i]*l[i];
        else sum+=min(h,l[i])*l[i]*l[i];
    }
    return v+sum < x*s ;
}
void solve() 
{
    scanf("%d",&t);
    for(;t;t--){
        scanf("%d",&n);
        ans = 0 ; k = 0 ; cnt = -1 ;
        for(int i=1;i<=n;i++){
            scanf("%lf %lf",&l[i],&p[i]);
        }
        scanf("%lf %lf %lf",&s,&h,&v);
        double L = v/s , R = h , mid ;
        while(R-L>eps){
            mid = (R+L)/2.0;
            if(check(mid)) R = mid ;
            else L = mid ;
        }
        printf("%.2f\n",L);
    }    
}
int main()
{
    /// open
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

 

The puzzle

 題面:

Kayaking is playing a puzzle game containing n different blocks. He marks the blocks with integers from 1 to n, which show the blocks’ original positions. Each time he can exchange two blocks and he wants to know how many times he needs at least to restore the puzzle.

InputThe input starts with one line contains exactly one positive integer which is the number of test cases.
Each test case contains two lines.
The first line contains an integer, which indicates the number of puzzle pieces.
The second line contains n different integers, the i-th number means the mark of the block in the i-th position.OutputFor each test case, output one line with one number represents the minimum operations.Sample Input

2
4
2 3 4 1
4
2 1 4 3

Sample Output

3
2

Hint

1<=T<=20,1<=n<=100000

題解:

暴力模擬

#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5+7 ;
#define ll long long
ll n,m,t,k,ans,cnt;
int a[mxn] ;
void solve() 
{
    for(cin>>t;t;t--){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        ans = 0 ;
        while(1){
            int ok = 1 ;
            for(int i=1;i<=n;i++){
                if(i!=a[i]){
                    swap(a[i],a[ a[i] ]);
                    ans++;
                    ok = 0 ;
                }
            }
            if(ok){
                cout<<ans<<endl;
                break;
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
View Code

 

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM