蒟蒻CC的补题日记——CF966

A——Primary Task

字符串读入按照题目要求判断一下就OK

#include<bits/stdc++.h>
using namespace std;

void solve()
{
    string s;
    cin>>s;
    if(s.size()<=2) 
    {
        cout<<"No\n";
        return;
    }
    if(s[0]!='1'||s[1]!='0')
    {
        cout<<"No\n";
        return;
    }
    if(s.size()==3)
    {
        if(s[2]>='2') cout<<"Yes\n";
        else cout<<"No\n";
        return;
    }
    if(s.size()>3)
    {
        if(s[2]=='0') cout<<"No\n";
        else cout<<"Yes\n";
    }

}

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

B——Seating in a Bus

用p数组记录一下1-n的乘客分别坐哪里,用st数组记录一下当前哪些位置有人坐,1-n的遍历一下p数组,除了第一次以外,每次判断一下 s t [ p [ i ] + 1 ] st[p[i]+1] st[p[i]+1] 或者 s t [ p [ i ] − 1 ] st[p[i]-1] st[p[i]1] 是否有人坐,没有人坐则返回No

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int st[N],p[N];
void solve()
{
    int n;
    cin>>n;
    for(int i=0;i<=n+1;i++) st[i]=0;
    for(int i=1;i<=n;i++)
        cin>>p[i];
    for(int i=1;i<=n;i++)
    {
        if(i==1) 
        {
            st[p[i]]=1;
            continue;
        }
        if(st[p[i]+1]==1||st[p[i]-1]==1) st[p[i]]=1;
        else 
        {
            cout<<"No\n";
            return;
        }
    }
    cout<<"Yes\n";
}

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

C——Numeric String Template

需要保证每个数字对应一个字母,每个字母对应一个数字,开两个Map存一下对应关系,如果没有冲突就输出Yes,否则输出No。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N];
void solve()
{
    ll n,q;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    cin>>q;
    while(q--)
    {
        int flg=1;
        map<char,ll> M1;
        map<ll,char> M2;
        string s;
        cin>>s;
        if(s.size()!=n)
        {
            cout<<"No\n";
            continue;
        }
        for(int i=0;i<s.size();i++)
        {
            if(M1.count(s[i])==0&&M2.count(a[i+1])==0)
            {
                M1[s[i]]=a[i+1];
                M2[a[i+1]]=s[i];
            } 
            else if(M1.count(s[i])!=0&&M2.count(a[i+1])!=0)
            {
                if(M1[s[i]]!=a[i+1]||M2[a[i+1]]!=s[i])
                {
                    flg=0;
                    break;
                }
            } 
            else 
            {
                flg=0;
                break;
            }
        }
        if(flg) cout<<"Yes\n";
        else cout<<"No\n";
    }
}

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

D——Right Left Wrong

为了使分数尽可能的多,就要尽可能的把每个数多加几次,分析可知首先先找到最中间的一对 L R LR LR,然后向右找 R R R,向左找 L L L,每找到一对 L R LR LR a n s ans ans 就加上 h [ d R ] − h [ d L − 1 ] h[d_R]-h[d_L-1] h[dR]h[dL1]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=2e5+10;
int p[N];
ll h[N];
char s[N];
int n;
ll check(int l,int r)
{
    ll ans=0;
    int dl=-1,dr=-1;
    for(int i=l+1;i<=r-1;i++)
    {
        if(s[i]=='L'&&dl==-1) 
        {
            dl=i;
            break;
        }
    }

    for(int i=r-1;i>=l+1;i--)
    {
        if(s[i]=='R'&&dr==-1) 
        {
            dr=i;
            break;
        }
    }
    // cout<<dl<<' '<<dr<<'\n';
    if(dl!=-1&&dr!=-1&&dr-dl>=1) 
    {
        // cout<<"!";
        ans=check(dl,dr);
    }
    ans+=h[r]-h[l-1];
    return ans;
}

void solve()
{
    int l=-1,r=-1;
    ll ans=0;
    cin>>n;
    for(int i=1;i<=n;i++) 
    {
        cin>>p[i];
        h[i]=h[i-1]+p[i];
    }
    cin>>s+1;

    for(int i=1;i<=n;i++)
    {
        if(s[i]=='L'&&l==-1) l=i;
        if(s[i]=='R') r=i;
    }

    if(l!=-1&&r!=-1) 
    {
        if(r-l>2) ans=check(l,r);
        else ans=h[r]-h[l-1];
        cout<<ans<<'\n';
    }
    else cout<<0<<'\n';
}
int main()
{
    ios
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}

E——Photoshoot for Gorillas

纯暴力,首先统计一下第一行和第一列中的每个格子可以在出现在几个 k ∗ k k*k kk的矩形中

第一行第 i i i v h [ i ] = m i n ( m i n ( i , n − i + 1 ) , m i n ( n − k + 1 , k ) ) v_h[i]=min(min(i,n-i+1),min(n-k+1,k)) vh[i]=min(min(i,ni+1),min(nk+1,k))

第一列第 i i i v w [ i ] = m i n ( m i n ( i , m − i + 1 ) , m i n ( m − k + 1 , k ) ) v_w[i]=min(min(i,m-i+1),min(m-k+1,k)) vw[i]=min(min(i,mi+1),min(mk+1,k))

然后遍历每个格子 n u m [ i ] [ j ] = v h [ i ] ∗ v w [ j ] num[i][j]=v_h[i]*v_w[j] num[i][j]=vh[i]vw[j],将所得的数存入数组 a a a 中从大到小排序

W W W 个大猩猩的身高存入数组 b b b 中从大到小排序,然后每次取 a a a 数组的最大乘上 b b b 数组的最大求和,直到 b b b 数组为空,

1.  #include<bits/stdc++.h>
1.  using namespace std;
1.  typedef long long ll;
1.   
1.  void solve()
1.  {
1.  int n,m,W,k;
1.  cin>>n>>m>>k;
1.  vector<ll> w,v;
1.  vector<ll> v_h(n+1),v_w(m+1);
1.  for(int i=1;i<=n;i++)
1.  v_h[i]=min(min(i,n-i+1),min(n-k+1,k));
1.  for(int i=1;i<=m;i++)
1.  v_w[i]=min(min(i,m-i+1),min(m-k+1,k));
1.   
1.  // for(int i=1;i<=n;i++)
1.  // cout<<v_h[i]<<' ';
1.  // for(int i=1;i<=m;i++)
1.  // cout<<v_w[i]<<' ';
1.  for(int i=1;i<=n;i++)
1.  {
1.  for(int j=1;j<=m;j++)
1.  {
1.  // cout<<v_h[i]*v_w[j]<<" ";
1.  w.push_back(v_h[i]*v_w[j]);
1.  }
1.  // cout<<'\n';
1.  }
1.  sort(w.begin(),w.end());
1.  // for(int i=0;i<w.size();i++) cout<<w[i]<<' ';
1.  // cout<<'\n';
1.  cin>>W;
1.  for(int i=1;i<=W;i++)
1.  {
1.  int x;
1.  cin>>x;
1.  v.push_back(x);
1.  }
1.  sort(v.begin(),v.end());
1.  // for(int i=0;i<v.size();i++) cout<<v[i]<<' ';
1.  ll ans=0;
1.  for(int i=v.size()-1,j=w.size()-1;i>=0;i--,j--)
1.  {
1.  ans+=(ll)v[i]*w[j];
1.  }
1.  cout<<ans<<'\n';
1.   
1.  }

F——Color Rows and Columns

简单的分组背包问题, v [ i ] [ j ] v[i][j] v[i][j] 表示第 i i i 个物品获得 j j j 个点数所需的点数(有点废话,其实不需要这个,写在这里只是为了与分组背包模板对应,我是蒟蒻 -_-悲.jpg), w [ i ] [ j ] w[i][j] w[i][j] 表示表示第 i i i 个物品获得 j j j 个点数所需操作的次数,重点就是处理 w [ i ] [ j ] w[i][j] w[i][j],贪心处理就行,对于每个矩形来说每次获得一个点数所需的操作数 n u m = m i n ( l , w ) num=min(l,w) num=min(l,w),然后 m a x ( l , w ) − 1 max(l,w)-1 max(l,w)1就行,这样贪心 ( l + w ) (l+w) (l+w) 次就 o k ok ok

/*   /\_/\
 *   (= ._.)
 *   / >  \>
 */      
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int v[1010][210],w[1010][210],s[1010];
int f[1010];

void solve()
{

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++) 
    {
        f[i]=inf;
    }
    for(int i=1;i<=n;i++)
    {
        int a,b,cnt=0;
        cin>>a>>b;
        s[i]=a+b;
        if(a>b) swap(a,b);
        while(a&&b)
        {
            ++cnt;
            v[i][cnt]=cnt;
            w[i][cnt]=w[i][cnt-1]+a;
            // cout<<w[i][cnt]<<'\n';
            b--;
            if(a>b) swap(a,b);
        }
        ++cnt;
        v[i][cnt]=cnt;
        w[i][cnt]=w[i][cnt-1];
    }

    f[0]=0;
     for(int i=1;i<=n;i++)
     {
        for(int j=m;j>=0;j--)
        {
            for(int k=0;k<=s[i];k++) 
                if(j>=v[i][k])     
                {
                    f[j]=min(f[j],f[j-v[i][k]]+w[i][k]);
                }
        }
        // cout<<'\n';
     }
    // for(int i=1;i<=m;i++)
    if(f[m]>inf/2)cout<<"-1\n";
    else cout<<f[m]<<'\n';
}

int main()
{
    int t;
    cin>>t;
    while(t--) solve();
    return 0;
}
  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值