Educational Codeforces Round 82 (Rated for Div. 2)(ABCDE部分题解)

A Erasing Zeroes

直接模拟

B National Project

算出最后一轮前需要几轮,然后加上剩余需要的天数。最后判断一下是不是比n小,如果是就再多做几天。
这题wa 3发心态小崩

#include
using namespace std;
int main()
{
    int T;cin>>T;
    while(T--){
        ll n, g, b;
        cin>>n>>g>>b;
        ll a = n;
        n = (n+1)/2;
        if(n == 0) {
            cout<<a<<endl; continue;
        }
        ll ans = (n-1)/g * (g+b);
        ans += n-(n-1)/g*g;
        if(ans < a) ans = a;
        cout<<ans<<endl;
    }
}

C Perfect Keyboard

键盘前两个字母根据密码确定之后后面的就都确定了。

#include
using namespace std;
int vis[26];
int main()
{
    int T;cin>>T;
    while(T--){
        string s; cin>>s;
        string ans; ans.clear();
        memset(vis, 0, sizeof vis);
        ans += s[0]; int c = 0;
        vis[s[0]-'a'] = 1;
        int f = 1;
        for(int i = 1; i < s.size(); ++i){
            int x = s[i]-'a';
            //cout<<"x:"<
            if(c+1 == ans.size() && !vis[x]){
                ans += s[i]; c++; vis[x] = 1;
            }else if(!vis[x]){
                vis[x] = 1;
                if(c == 0) ans = (char)(s[i])+ans;
                else {f = 0; break;}
            }else{
                if(c+1 < ans.size() && ans[c+1] == s[i]) c++;
                else if(c-1 >= 0 && ans[c-1] == s[i]) c--;
                else {f = 0; break;}
            }
        }
        if(!f) cout<<"NO"<<endl;
        else {
            cout<<"YES"<<endl;
            for(int i = 0; i < 26; ++i) if(!vis[i]) ans += (char)(i+'a');
            cout<<ans<<endl;
        }
    }
}

D Fill The Bag

判断一下Sum是不是小于n,小于n肯定无解,否则一定有解(全部换成1)
然后从n的低位开始凑,凑完低位之后这一位剩下的都可以往上合成。如果这一位没有,就往上找,从上面翻下来。因为输入的 a i a_i ai小于1e9所以只要做到30位就足够了。

#include
#define ll long long
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mid ((l+r)>>1)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
int vis[64];
int main()
{
    int T;cin>>T;
    while(T--){
            memset(vis,0,sizeof vis);
        ll n; cin>>n;
        int m; cin>>m;
        ll sum = 0;
        while(m--){
            int x; scanf("%d", &x);
            for(int i = 0; i < 30; ++i) if(x>>i&1) {vis[i]++; break;}
            sum += x;
        }
        if(sum < n){
            cout<<-1<<endl; continue;
        }
        int ans = 0;
        for(int i = 0; i < 32; ++i){
            if(n>>i&1){
                if(vis[i])  vis[i]--;
                else {
                    for(int j = i+1; j < 32; ++j){
                        if(vis[j]){
                            while(j > i) {
                                vis[j]--;
                                j--; vis[j] += 2;
                                ans++;
                            }
                            break;
                        }
                    }
                    vis[i]--;
                }
            }
            vis[i+1]+=(vis[i]/2);
        }
        cout<<ans<<endl;
    }
}

E Erase Subsequences

枚举分裂点,分成两个串。然后 d p ( i , j ) dp(i,j) dp(i,j)表示第一串匹配到 i i i,第二串匹配到 j j j至少需要匹配到 s s s的第几个位置去判断。

#include
#define ll long long
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mid ((l+r)>>1)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
const int maxn = 405;
int nxt[405][26];
char s[maxn];
char t[maxn];
int n;
int dp[maxn][maxn];
bool go(int n1, char *a, int n2, char *b){
    dp[0][0] = 0;
    for(int i = 0; i <= n1; ++i){
        for(int j = 0; j <= n2; ++j){
            if(i+j == 0) continue;
            dp[i][j] = n+1;
            if(i) dp[i][j] = min(dp[i][j], nxt[dp[i-1][j]][a[i]-'a']);
            if(j) dp[i][j] = min(dp[i][j], nxt[dp[i][j-1]][b[j]-'a']);
        }
    }
    return dp[n1][n2] <= n;
}
int main()
{
    int T; cin>>T;
    while(T--){
        scanf("%s", s+1);
        scanf("%s", t+1);
        n = strlen(s+1);
        for(int i = 0; i < 26; ++i) nxt[n][i] = nxt[n+1][i] = n+1;
        for(int i = n-1;i >= 0;--i){
            for(int j = 0;j < 26;++j) nxt[i][j] = nxt[i+1][j];
                nxt[i][s[i+1]-'a'] = i + 1;
        }
        int f = 1;
        int p = 0;
        int len = strlen(t+1);
        for(int i = 1; i <= len; ++i){
            int x = t[i]-'a';
            p = nxt[p][x];
            if(p == n+1) f = 0;
        }
        if(f){
            cout<<"YES"<<endl; continue;
        }

        for(int i = 1; i < len; ++i){
            if(f) break;
            if(go(i, t, len-i, t+i)){
                f = 1;
            }
        }
        if(f) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}
/*
1
defi
fed
*/

你可能感兴趣的:(练习)