Codeforces Round #547 (Div3)

版权声明:转载请注明出处哦。 https://blog.csdn.net/Dch19990825/article/details/88678132

A. Game 23

思路:

深搜即可

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn=120;
const int inf=0x3f3f3f3f;
ll m;
int dfs(ll val,int s)
{
    if(val==m)
        return s;
    if(val>m)
        return -1;
    int ans=dfs(val*2ll,s+1);
    if(ans!=-1)
        return ans;
    ans=dfs(val*3ll,s+1);
    return ans;
}
int main()
{
    ll n;
    cin>>n>>m;
    cout<<dfs(n,0);
    return 0;
}

B. Maximal Continuous Rest

思路:

把序列*2 ,找出最长连续1即可

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn=4e5+100;
const int inf=0x3f3f3f3f;
int Tt[maxn];
int n;
int main()
{
    cin>>n;
    for(int i=0; i<n; ++i)
    {
        cin>>Tt[i];
        Tt[i+n]=Tt[i];
    }
    int ans=0,maxx=0;
    for(int i=0; i<2*n; ++i)
    {
        if(Tt[i]==0){
            ans=0;
            continue;
        }
        if(i==0||Tt[i]==Tt[i-1])
            ans++;
        else
            ans=1;
        maxx=max(maxx,ans);
    }
    cout<<maxx<<endl;
    return 0;
}

C. Polycarp Restores Permutation

思路:

将所有的 p i p_{i} p 1 p_1 作差,记下差和下标 i i ,最后排序即可。排序后的顺序就是1、2、3…

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn=2e5+100;
const int inf=0x3f3f3f3f;
pair<int,int>mm[maxn];
int Val[maxn];
int main()
{
    int n;
    cin>>n;
    mm[1].first=0;//first 代表插值  second 代表下标
    mm[1].second=1;
    int sum=0,w;
    for(int i=2;i<=n;++i){
        cin>>w;
        sum+=w;
        mm[i].first=sum;
        mm[i].second=i;
    }
    sort(mm+1,mm+n+1);
    int flag=1;
    Val[mm[1].second]=1;
    for(int i=2;i<=n;++i){
        if(mm[i].first-mm[i-1].first!=1){
            flag=0;
            break;
        }
        else{
            Val[mm[i].second]=i;
        }
    }
    if(!flag){
        printf("-1\n");
    }
    else{
        for(int i=1;i<=n;++i)
            printf("%d%c",Val[i],i==n?'\n':' ');
    }
    return 0;
}

D. Colored Boots

思路:贪心思想

​ 先将s1的字符类型和对应的位置储存起来,然后对于s2的每一个字符

  • ​ 如果为字母则匹配s1中的字母,否则匹配s1的一个问号,没问号则不匹配
  • ​ 为问号则储存起来

最后将s2的问号与s1的字符一顿瞎匹配即可。

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn=15e4+100;
const int inf=0x3f3f3f3f;
int hashC(char c)
{
    if(c=='?')
        return 26;
    return c-'a';
}
vector<int> ma[30]; //存储下标
string s;
vector<int> s2;//存储s2的问号
int ans[2][maxn],tot;
int n;
int main()
{
    cin>>n>>s;
    for(int i=0;i<n;++i)
    {
        ma[hashC(s[i])].push_back(i+1);//在对应容器后面加上下标
    }
    cin>>s;
    for(int i=0;i<n;++i)
    {
        if(s[i]=='?'){
            s2.push_back(i+1);
        }
        else{
            int pc=hashC(s[i]);
            if(ma[pc].empty()){
                //找问号
                if(ma[26].empty())
                    continue;
                else{
                    ans[0][tot]=i+1;
                    ans[1][tot]=ma[26][ma[26].size()-1];
                    tot++;
                    ma[26].pop_back();
                }
            }
            else{
                ans[0][tot]=i+1;
                ans[1][tot]=ma[pc][ma[pc].size()-1];
                tot++;
                ma[pc].pop_back();
            }
        }
    }
    
    for(int i=0;i<s2.size();++i){
        ans[0][i+tot]=s2[i];
    }
    int nowt=s2.size();
    while(nowt){
        for(int i=0;i<=26;++i)
        {
            if(!ma[i].empty()){
                ans[1][tot++]=ma[i][ma[i].size()-1];
                ma[i].pop_back();
                nowt--;
            if(nowt==0)
                break;
            }

        }
    }
    cout<<tot<<endl;
    for(int i=0;i<tot;++i){
        printf("%d %d\n",ans[1][i],ans[0][i]);
    }
    return 0;
}

E. Superhero Battle

思路:

​ 如果可以直接一轮打死则直接 f o r for 循环找出第 i i 天死,输出 i i 即可

​ 否则,设一轮中最大减少的血量为maxhp(带上前面几分钟减少的), 回合结束后共减少的血量为sumhp

  • ​ 如果hp<maxhp 且sumhp>=0 无解
  • ​ 令k= (hp-maxhp)/sumhp+bool((hp-maxhp)%sumhp) 则他在k+1天死,
#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn=2e5+100;
const int inf=0x3f3f3f3f;
/*
1.一轮中 可以减少的血量的最大血量 maxhp
2.一轮中 可以减少的血量 sumhp
if(可以一轮直接死 hp<=maxhp)
{

}
否则计算 经过第k论 第k+1轮直接死
k=(hp-maxhp)/sumhp
if mod=(hp-maxhp)%sumhp  在第k轮不能直接死 ,剩余mod  判断mod/sumhp+bool(mod%sumhp) 需要addk

最后一回合在第i天死
输出第k*n+i即可
*/
ll deVal[maxn];//存储 第 i分钟的最大减少血量
ll sumhp,hp,n,k,mod,maxhp;
int main()
{
    cin>>hp>>n;
    for(int i=1; i<=n; ++i)
    {
        ll w;
        cin>>w;
        deVal[i]=deVal[i-1]+w;
        maxhp=min(maxhp,deVal[i]);
    }
    sumhp=deVal[n]*-1;
    maxhp*=-1;
    if(maxhp<hp&&sumhp<=0)
    {
        printf("-1\n");
        return 0;
    }
    k=0;
    if(maxhp<hp){
        k=(hp-maxhp)/sumhp;
        mod=(hp-maxhp)%sumhp;
        k+=mod/sumhp+bool(mod%sumhp);
        hp-=sumhp*k;
    }
    //可以一下杀死  求出第i个即可
    for(int i=1;i<=n;++i)
    {
        if(deVal[i]*-1>=hp)
        {
            cout<<k*n+i<<endl;
            return 0;
        }
    }
//    cout<<"k:"<<k<<"hp:"<<hp<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dch19990825/article/details/88678132