Codeforces Round #657 (Div. 2) 题解

Problem A

题面

Acacius is studying strings theory. Today he came with the following problem.

You are given a string s of length n consisting of lowercase English letters and question marks. It is possible to replace question marks with lowercase English letters in such a way that a string "abacaba" occurs as a substring in a resulting string exactly once?

Each question mark should be replaced with exactly one lowercase English letter. For example, string "a?b?c" can be transformed into strings "aabbc" and "azbzc", but can't be transformed into strings "aabc", "a?bbc" and "babbc".

Occurrence of a string t of length m in the string s of length n as a substring is a index i (1≤i≤n−m+1) such that string s[i..i+m−1] consisting of m consecutive symbols of s starting from i-th equals to string t. For example string "ababa" has two occurrences of a string "aba" as a substring with i=1 and i=3, but there are no occurrences of a string "aba" in the string "acba" as a substring.

Please help Acacius to check if it is possible to replace all question marks with lowercase English letters in such a way that a string "abacaba" occurs as a substring in a resulting string exactly once.

Input
First line of input contains an integer T (1≤T≤5000), number of test cases. T pairs of lines with test case descriptions follow.

The first line of a test case description contains a single integer n (7≤n≤50), length of a string s.

The second line of a test case description contains string s of length n consisting of lowercase English letters and question marks.

Output
For each test case output an answer for it.

In case if there is no way to replace question marks in string s with a lowercase English letters in such a way that there is exactly one occurrence of a string "abacaba" in the resulting string as a substring output "No".

Otherwise output "Yes" and in the next line output a resulting string consisting of n lowercase English letters. If there are multiple possible strings, output any.

You may print every letter in "Yes" and "No" in any case you want (so, for example, the strings yEs, yes, Yes, and YES will all be recognized as positive answer).

思路

直接上暴力,第一遍不管问号如果大于1直接输出no,等于1直接输出yes,问号换成z就可以了。第二遍去改变问号的匹配,使得他尽量出现要求的串,得到后就break输出,不然直接say no。

代码实现

#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define MT(x,i) memset(x,i,sizeof(x) )
#define rev(i,start,end) for (int i=start;i<end;i++)
#define inf 0x3f3f3f3f
#define mp(x,y) make_pair(x,y)
#define lowbit(x) (x&-x)
#define exp 1e-8
#define N 1000005 
#define fi first 
#define se second
#define pb push_back
const int mod=1e9+7;
typedef long long ll;
typedef vector <int> VI;
typedef pair<int ,int> PII;
typedef pair<int ,PII> PIII;
ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
inline int read() {
    char ch=getchar(); int x=0, f=1;
    while(ch<'0'||ch>'9') {
        if(ch=='-') f=-1;
        ch=getchar();
    } while('0'<=ch&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    } return x*f;
}

int t,n;
string s="abacaba";
string s2;

int count (string str) {
    int flag,ans=0;
    rep (i,0,str.size ()-7) {
        flag=1;
        rev (j,0,7) {
          if (str[i+j]!=s[j]) {
              flag=0;
              break;
          }
        }
        if (flag) ans++;
    }
    return ans;
}

inline void print (string s) {
    cout<<"Yes"<<endl;
    rev (i,0,s.size ()) {
        if (s[i]=='?') s[i]='z';
    }
    cout<<s<<endl;
}

inline void solve () {
    cin>>n;
    cin>>s2;
    int k=count (s2),flag,sign=0;
    if (k>1) {
        cout<<"No"<<endl;
        return ;
    }
    if (k==1) {
        print (s2);
        return ;
    }
    string temp=s2;
    rep (i,0,s2.size ()-7) {
       s2=temp;
        flag=1;
        rev (j,0,7) {
            if (s2[i+j]=='?') s2[i+j]=s[j];
            if (s2[i+j]!=s[j]) {
                flag=0;
                break;
            } 
        }
        if (flag) {
            k=count (s2);
            if (k==1) {
                print (s2);
                sign=1;
            }
        }
        if (sign) break;
    }
    if (!sign) cout<<"No"<<endl;
    return ;

}

int main () {
    cin>>t;
    while (t--) {
        solve ();
    }
    return 0;
}

Problem B

题目

Pasha loves to send strictly positive integers to his friends. Pasha cares about security, therefore when he wants to send an integer n, he encrypts it in the following way: he picks three integers a, b and c such that l≤a,b,c≤r, and then he computes the encrypted value m=n⋅a+b−c.

Unfortunately, an adversary intercepted the values l, r and m. Is it possible to recover the original values of a, b and c from this information? More formally, you are asked to find any values of a, b and c such that

a, b and c are integers,
l≤a,b,c≤r,
there exists a strictly positive integer n, such that n⋅a+b−c=m.
Input
The first line contains the only integer t (1≤t≤20) — the number of test cases. The following t lines describe one test case each.

Each test case consists of three integers l, r and m (1≤l≤r≤500000, 1≤m≤1010). The numbers are such that the answer to the problem exists.

Output
For each test case output three integers a, b and c such that, l≤a,b,c≤r and there exists a strictly positive integer n such that n⋅a+b−c=m. It is guaranteed that there is at least one possible solution, and you can output any possible combination if there are multiple solutions.

思路

首先把式子化简,然后发现只要a可以被m整除那么显然存在n,否则的话我们去根据余数凑整,分两种情况讨论。

代码实现

#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define MT(x,i) memset(x,i,sizeof(x) )
#define rev(i,start,end) for (int i=start;i<end;i++)
#define inf 0x3f3f3f3f
#define mp(x,y) make_pair(x,y)
#define lowbit(x) (x&-x)
#define exp 1e-8
#define N 1000005 
#define fi first 
#define se second
#define pb push_back
const int mod=1e9+7;
typedef long long ll;
typedef vector <int> VI;
typedef pair<int ,int> PII;
typedef pair<int ,PII> PIII;
ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
inline int read() {
    char ch=getchar(); int x=0, f=1;
    while(ch<'0'||ch>'9') {
        if(ch=='-') f=-1;
        ch=getchar();
    } while('0'<=ch&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    } return x*f;
}

ll t,n,l,r,m;

inline void solve () {
    cin>>l>>r>>m;
    ll a,b,c;
    // if (m>=l&&m<=r) {
    //     cout<<m<<" "<<l<<" "<<l<<endl;
    //     return ;
    // }
    rep (i,l,r) {
        ll c1=m%i,c2=i-m%i;
        a=i;
        if (c2<=r-l) {
            b=l,c=l+c2;
            break;
        }
        else if (c1<=r-l) {
            b=l+c1,c=l;
            break;
        }
    }
    cout<<a<<" "<<b<<" "<<c<<endl;
}

int main () {
    cin>>t;
    while (t--) {
        solve ();
    }
    return 0;
}

Problem C

题目

Vladimir would like to prepare a present for his wife: they have an anniversary! He decided to buy her exactly n flowers.

Vladimir went to a flower shop, and he was amazed to see that there are m types of flowers being sold there, and there is unlimited supply of flowers of each type. Vladimir wants to choose flowers to maximize the happiness of his wife. He knows that after receiving the first flower of the i-th type happiness of his wife increases by ai and after receiving each consecutive flower of this type her happiness increases by bi. That is, if among the chosen flowers there are xi>0 flowers of type i, his wife gets ai+(xi−1)⋅bi additional happiness (and if there are no flowers of type i, she gets nothing for this particular type).

Please help Vladimir to choose exactly n flowers to maximize the total happiness of his wife.

Input
The first line contains the only integer t (1≤t≤10000), the number of test cases. It is followed by t descriptions of the test cases.

Each test case description starts with two integers n and m (1≤n≤109, 1≤m≤100000), the number of flowers Vladimir needs to choose and the number of types of available flowers.

The following m lines describe the types of flowers: each line contains integers ai and bi (0≤ai,bi≤109) for i-th available type of flowers.

The test cases are separated by a blank line. It is guaranteed that the sum of values m among all test cases does not exceed 100000.

Output
For each test case output a single integer: the maximum total happiness of Vladimir's wife after choosing exactly n flowers optimally.

思路

贪心,我们发现只要在允许的范围内去把比b值最大的a值全拿一遍,剩下的全部拿最大的b就好了。

代码实现

#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define MT(x,i) memset(x,i,sizeof(x) )
#define rev(i,start,end) for (int i=start;i<end;i++)
#define inf 0x3f3f3f3f
#define mp(x,y) make_pair(x,y)
#define lowbit(x) (x&-x)
#define exp 1e-8
#define N 1000005 
#define fi first 
#define se second
#define pb push_back
const int mod=1e9+7;
typedef long long ll;
typedef vector <int> VI;
typedef pair<int ,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<int ,PII> PIII;
ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
inline int read() {
    char ch=getchar(); int x=0, f=1;
    while(ch<'0'||ch>'9') {
        if(ch=='-') f=-1;
        ch=getchar();
    } while('0'<=ch&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    } return x*f;
}

const int maxn=1e5+10;
int t,n,m;
PLL a[maxn];

int findsit (ll val) {
    int l=1,r=m,ans=0;
    while (l<=r) {
        int mid=(l+r)>>1;
        if (a[mid].first>val) {
            ans=mid;
            l=mid+1;
        }
        else {
            r=mid-1;
        }
    }
    return ans;
}

inline void solve () {
    int ind=0,cnt=0,hb=0;
    ll sum[maxn]={0};
    ll ans=0,res=0;
    cin>>n>>m;
    rep (i,1,m) cin>>a[i].first>>a[i].second;
    sort (a+1,a+m+1,greater <PLL>());
    rep (i,1,m) sum[i]=sum[i-1]+a[i].first;
    rep (i,1,m) {
        ind=findsit (a[i].second);
        cnt=min (ind,n-1);
        res=sum[cnt];
        hb=n-cnt;
        if (i>cnt) {
            res+=a[i].first;
            hb--;
        }
        res+=1LL*hb*a[i].second;
        ans=max (ans,res);
    }
    cout<<ans<<endl;
    return ;
}

int main () {
    cin>>t;
    while (t--) {
        solve ();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hhlya/p/13551111.html