Codeforces Round #578 (Div. 2) 題解報告

A. Hotelier
sb模擬,直接按題意模擬就可以了。
B. Block Adventure

Gildong is playing a video game called Block Adventure. In Block Adventure, there are n columns of blocks in a row, and the columns are numbered from 1 to n. All blocks have equal heights. The height of the i-th column is represented as hi, which is the number of blocks stacked in the i-th column.

Gildong plays the game as a character that can stand only on the top of the columns. At the beginning, the character is standing on the top of the 1-st column. The goal of the game is to move the character to the top of the n-th column.

The character also has a bag that can hold infinitely many blocks. When the character is on the top of the i-th column, Gildong can take one of the following three actions as many times as he wants:

if there is at least one block on the column, remove one block from the top of the i-th column and put it in the bag;
if there is at least one block in the bag, take one block out of the bag and place it on the top of the i-th column;
if i<n and |hi−hi+1|≤k, move the character to the top of the i+1-st column. k is a non-negative integer given at the beginning of the game. Note that it is only possible to move to the next column.
In actions of the first two types the character remains in the i-th column, and the value hi changes.

The character initially has m blocks in the bag. Gildong wants to know if it is possible to win the game. Help Gildong find the answer to his question.

Input
Each test contains one or more test cases. The first line contains the number of test cases t (1≤t≤1000). Description of the test cases follows.

The first line of each test case contains three integers n, m, and k (1≤n≤100, 0≤m≤106, 0≤k≤106) — the number of columns in the game, the number of blocks in the character’s bag at the beginning, and the non-negative integer k described in the statement.

The second line of each test case contains n integers. The i-th integer is hi (0≤hi≤106), the initial height of the i-th column.

Output
For each test case, print “YES” if it is possible to win the game. Otherwise, print “NO”.

You can print each letter in any case (upper or lower).

題意,感覺表達有點亂。站在一個h[i]個方塊壘起來的地方,可以無限拿方塊,也可以放方塊,當 abs(h[i]-h[i+1]) <= K的時候可以進到下一個。否則無法過去。
做法:直接貪心就可以了,拿當前最多能拿的方塊,放當前最少需要的方塊。模擬能不能到達最後一層就可以了。
代碼如下:

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int MAX = 110;
ll h[MAX];
ll N,M,K;
bool solve(){
    for(int i=1;i<N;++i){
        if(h[i] >= h[i+1]-K){//當前方塊多,即可不斷的拿
            M += h[i]-max(0LL,(h[i+1]-K));//注意最少也是0,不能出現負數
        }
        else{
            if(h[i]+M >= h[i+1]-K){
                M -= ((h[i+1]-K)-h[i]);//最少需要補得方塊。
            }
            else{
                return false;
            }
        }
    }
    return true;
}
int main(void){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld",&N,&M,&K);
        for(int i=1;i<=N;++i){
            scanf("%lld",&h[i]);
        }
        if(solve()){
            cout << "YES" << endl;
        }
        else{
            cout << "NO" << endl;
        }
    }
 
    return 0;
}

C. Round Corridor
Amugae is in a very large round corridor. The corridor consists of two areas. The inner area is equally divided by n sectors, and the outer area is equally divided by m sectors. A wall exists between each pair of sectors of same area (inner or outer), but there is no wall between the inner area and the outer area. A wall always exists at the 12 o’clock position.
在這裏插入圖片描述

The inner area’s sectors are denoted as (1,1),(1,2),…,(1,n) in clockwise direction. The outer area’s sectors are denoted as (2,1),(2,2),…,(2,m) in the same manner. For a clear understanding, see the example image above.

Amugae wants to know if he can move from one sector to another sector. He has q questions.

For each question, check if he can move between two given sectors.

Input
The first line contains three integers n, m and q (1≤n,m≤1018, 1≤q≤104) — the number of sectors in the inner area, the number of sectors in the outer area and the number of questions.

Each of the next q lines contains four integers sx, sy, ex, ey (1≤sx,ex≤2; if sx=1, then 1≤sy≤n, otherwise 1≤sy≤m; constraints on ey are similar). Amague wants to know if it is possible to move from sector (sx,sy) to sector (ex,ey).

Output
For each question, print “YES” if Amugae can move from (sx,sy) to (ex,ey), and “NO” otherwise.

You can print each letter in any case (upper or lower).

Example
inputCopy
4 6 3
1 1 2 3
2 6 1 2
2 6 2 4
outputCopy
YES
NO
YES
Note
Example is shown on the picture in the statement.

做法:
內部每個扇形的度數是 (360/n),外部的每個扇形角度是 (360/m)。設內部第a個扇形和外部第b個扇形剛好度數和相等,即構成一個封閉的門。a* (360/n) = b*(360/m) 化簡後可以知道。a/b = n/m;也就是a 和n是對應成比例的,b 和m是對應成比例的。
n 和 m 除以二者最大gcd後記爲 n’ m’,則可以通過py,ey求出對應在第幾個門前面,判斷兩個座標在不在同一個門當中即可。

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
ll N,M,Q;
ll sx,sy,ex,ey;
ll get(ll num,bool inner){
    if(inner){
        if(num % N == 0)
            return num/N;
        else
            return num/N+1;
    }
    else{
        if(num % M == 0)
            return num/M;
        else
            return num/M+1;
    }
}
bool solve(){
    ll ps,pe;
    ps = get(sy,sx == 1);
    pe = get(ey,ex == 1);
    if(ps == pe)
        return true;
    else
        return false;
}
int main(void){
    scanf("%lld%lld%lld",&N,&M,&Q);
 
    ll GCD = __gcd(N,M);
    N/=GCD;M/=GCD;
    for(int i=1;i<=Q;++i){
        scanf("%lld%lld%lld%lld",&sx,&sy,&ex,&ey);
        if(solve()){
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

E. Compress Words
Amugae has a sentence consisting of n words. He want to compress this sentence into one word. Amugae doesn’t like repetitions, so when he merges two words into one word, he removes the longest prefix of the second word that coincides with a suffix of the first word. For example, he merges “sample” and “please” into “samplease”.

Amugae will merge his sentence left to right (i.e. first merge the first two words, then merge the result with the third word and so on). Write a program that prints the compressed word after the merging process ends.

Input
The first line contains an integer n (1≤n≤105), the number of the words in Amugae’s sentence.

The second line contains n words separated by single space. Each words is non-empty and consists of uppercase and lowercase English letters and digits (‘A’, ‘B’, …, ‘Z’, ‘a’, ‘b’, …, ‘z’, ‘0’, ‘1’, …, ‘9’). The total length of the words does not exceed 106.

Output
In the only line output the compressed word after the merging process ends as described in the problem.

Examples
inputCopy
5
I want to order pizza
outputCopy
Iwantorderpizza
inputCopy
5
sample please ease in out
outputCopy
sampleaseinout

題意:把相同的前後綴去重,然後從左到右合併單詞。問你最後壓縮出來的串是多少。

做法:很顯然需要一個算法能O(N)的求出相同前後綴的長度即可。我用的是字符串哈希的方法。
比賽過了,賽後卻掛了。。。哎,自己最開始只用了一個base,以及用的自然溢出。當時猜想到可以回出現哈希碰撞。哎,可惜時間不太夠了。。這次用了三個base,加mod 不用自然溢出,過了。似乎用兩個就可以通過。
代碼如下:

#include<bits/stdc++.h>
 
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
ll Mod1 = 1e9+7,Mod2 = 998244353,Mod3 = 19971205;
ll B1 = 131,B2 = 13131,B3 = 1331;
int overlap(string &a,string &b){
    int al = a.length(),bl = b.length();
    int ans = 0;
    ll ah1 = 0,ah2 = 0,ah3 = 0;
    ll bh1 = 0,bh2 = 0,bh3 = 0;
    ll t1= 1,t2 = 1,t3 = 1;
 
    for(int i=1;i<=min(al,bl);++i){
        ah1 = ah1 + a[al-i]*t1;ah1 %= Mod1;
        ah2 = ah2 + a[al-i]*t2;ah2 %= Mod2;
        ah3 = ah3 + a[al-i]*t3;ah3 %= Mod3;
 
        bh1 = bh1*B1 + b[i-1];bh1 %= Mod1;
        bh2 = bh2*B2 + b[i-1];bh2 %= Mod2;
        bh3 = bh3*B3 + b[i-1];bh3 %= Mod3;
        if(ah1 == bh1 && ah2 == bh2 && ah3 == bh3)
            ans = i;
 
        t1 = t1*B1%Mod1;
        t2 = t2*B2%Mod2;
        t3 = t3*B3%Mod3;
    }
    return ans;
}
 
int main(void){
 
    int N;
    string res = "";
    string last = "";
    string str;
    cin >> N;
    for(int i=1;i<=N;++i){
        cin >> str;
        if(i == 1){
            res = str;
        }
        else{
            int len = overlap(res,str);
            res += str.substr(len);
        }
    }
    cout << res << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章