Educational Codeforces Round 137 (Rated for Div. 2)


一、Password

  • 题目:给你一把密码锁,锁由4个0~9的数字组成,且是由两对相同的数字组成,给你锁中绝对不会出现的数字,问你这个锁有多少种方法可以组成
  • 思路:数学,因为只有两个数字相同,数字选择一共有10 - n种选择,从中间选择两个,然后两个数字能够组成6种,再乘6就行
  • 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>

using namespace std;

const int N = 2e5 + 100,mod=998244353;
int a[N];
vector<int> res;

void solve()
{
    int n; cin >> n;
    for(int i = 1;i <= n;i ++ ) cin >> a[i];
    n = 10 - n;
    cout << n * (n - 1) / 2 * 6 << endl;
}

signed main() 
{
    ios::sync_with_stdio(false); cin.tie(0);
    int T; cin >> T;
    while(T -- ) solve();

}

二、Permutation Value

  • 题目:构造一个排列,使得这个排列中的子序列为排列的个数最少
  • 思路:当n >= 2时,排列方法都是2,除了1,就是整体,所以搞一个这样的排列就行,把n放在1后面
  • 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>

using namespace std;

const int N = 2e5 + 100,mod=998244353;
int a[N];
vector<int> res;

void solve()
{
    int n; cin >> n;
    for(int i = 1;i <= n;i ++ )
    if(i == 1) cout << 1 << ' ';
    else if(i == 2) cout << n << ' ';
    else cout << i - 1 << ' ';
    cout << endl;
}

signed main() 
{
    ios::sync_with_stdio(false); cin.tie(0);
    int T; cin >> T;
    while(T -- ) solve();

}

三、Permutation Value

  • 题目:有n个箱子,每个箱子里面都有a[i]个报纸,有的箱子被抹布盖住,有的没有,问你执行操作以后,所有的抹布最多能够盖住多少张报纸
    操作:每块抹布都可以移动,但是只能向左移动一格(0表示盒子没有被盖住,1相反)
  • 思路:每一段里面都找最后一个0出现的位置(因为只能向左移动一格),然后由后面一连串的1来判断是否需要向左移动,如果被盖住的盒子里面报纸的数量 < 0位置盒子里面的报纸数量的话,就让这一连串的1统一 向左移动一格(贪心),这样更优,便利一遍就行
  • 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
// #define int long long
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>

using namespace std;

const int N = 2e5 + 100,mod=998244353;
int a[N];
priority_queue<int> q;
void solve()
{
    int n; cin >> n;
    
    int sum = 0; 
    string s; cin >> s; s = "?" + s;
    for(int i = 1;i <= n;i ++ ) cin >> a[i];
    
    for(int i = 1;i <= n - 1;i ++ )
    {
        if(s[i] == '0' && s[i + 1] == '1')
        {
            int j = i + 1;
            while(j <= n && a[j] >= a[i] && s[j] == '1')
            {
                j ++ ;
                
            }
            
            if(j <= n && a[j] < a[i])
            {
               
                swap(s[i],s[j]);
            }
            
            i = j - 1;
        }
    }
    
    for(int i = 1;i <= n;i ++ )
    if(s[i] == '1')
    sum += a[i];
    
    //cout << s << endl;
    cout << sum << endl;
  
}

int main() 
{
    ios::sync_with_stdio(false); cin.tie(0);
    int T; cin >> T;
    while(T -- ) solve();

}

四、 Problem with Random Tests

  • 题目:给你一个01串,问你哪两个字串之后值最大?
  • 思路:因为是随机数,所以暴力就行,首先题目要求最大,所以其中一个子串就是它本身,另一个串要满足其他的条件
  • 条件1 :就是找到前面有1的第一个0的位置pos,比如000110011,位置就是6,然后每一次选取的字串长度必须是n - pos + 1,选取的范围是1
  • 代码:
#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n; cin >> n;
    string s; cin >> s; s = "?" + s;
    int f = 0,pos = 1;
    for(int i = 1;i <= n;i ++ )
    {
        if(s[i] == '1') f = 1;
        if(f && s[i] == '0')
        {
            pos = i;
            break;
        }
    }
    
     string ans;
    for(int i = pos;i <= n;i ++ )
    ans += s[i];
    
   
    int len = n - pos + 1;// 匹配的长度最多是这个
    //cout <<len << endl;
    for(int i = 1;i < pos;i ++ )
    {
        if(s[i] == '0') continue; // i就是起点
        string res;
        for(int j = i,k = pos; j <= i + len - 1;j ++,k ++)
        if(s[j] == '1' || s[k] == '1')
        res += "1";
        else
        res += "0";
       
        ans = max(ans,res);
    }
    string u;
    for(int i = 1;i < pos;i ++ )
    u += s[i];
    ans = u + ans;
    ans = "?" + ans;
    bool ff = false;
    for(int i = 1;i < ans.size();i ++ )
    {
        if(ans[i] == '1') ff = true;
        if(ff) cout << ans[i];
    }
    
    if(!ff) cout << "0" << endl;
    else cout << endl;
    
    
    return 0;
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值