Codeforces Round 253 (Div. 2)



layout: post
title: Codeforces Round 253 (Div. 2)
author: "luowentaoaa"
catalog: true
tags:
mathjax: true
- codeforces
- 模拟栈
- 贪心



传送门

A.Anton and Letters (签到)

题意

判断字符串里面有多少个不同字符

思路

直接set一下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
set<char>st;
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    string s;
    getline(cin,s);
    int len=s.size();
    for(int i=0;i<len;i++){
        if(s[i]>='a'&&s[i]<='z')st.insert(s[i]);
    }
    cout<<st.size();
    return 0;
}

B.Kolya and Tandem Repeat (暴力模拟)

题意

给你一个字符串,你可以在末尾添加K个任意字符 ,让你找出一个最长的重复两次的字串

思路

直接暴力模拟

对于每个字串长度,字串起点,开始判断,复杂度n^3

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    string ss;
    cin>>ss;
    string s="";s+='*';s+=ss;
    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        s+='*';
    }
    int ans=0;
    int len=s.size()-1;
    for(int i=1;i<len;i++){
        for(int j=1;j<len;j++){
            if(i+2*j-1>len)continue;
            int head=i,tail=i+j,flag=0;
            for(int k=1;k<=j;k++){
                if(s[head+k-1]=='*'||s[tail+k-1]=='*'||s[head+k-1]==s[tail+k-1])continue;
                flag=1;
            }
            if(!flag)ans=max(ans,j*2);
        }
    }
    cout<<ans;
    return 0;
}

C.Borya and Hanabi (大模拟,二进制模拟)

题意

现在有五种花色五种数字组成的二十五张牌,你手里有诺干张牌,每次你可以询问一种颜色和一种数字,你会得到所有这个花色/数字牌的位置,问你最少多少次可以把所有的牌分类

思路

把题目抽象成一个二维坐标,花色为横坐标,数字为纵坐标,每次可以连接一条线,把一条线上的牌找到,对于一张牌有两种找到方法,

1.这张牌被两条线连接,也就是花色和数字都固定了,

2.这张牌的其他花色或其他数字都被找到了,那么剩下的就只有他了

可以发现我们最多只要连接十条线,所以我们可以直接子集模拟一下十条线的搭配

然后暴力判断能否在这种情况分出任意两张牌

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int x[maxn];
int y[maxn];
void who(string s,int i){
    char top=s[0];
    if(top=='B')x[i]=0;
    else if(top=='Y')x[i]=1;
    else if(top=='W')x[i]=2;
    else if(top=='G')x[i]=3;
    else x[i]=4;
    y[i]=s[1]-'1';
}
int n;
int bit(int i){return 1<<i;}
bool check (int sta) {
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(x[i]==x[j]){
                if( y[i]!=y[j] && (sta&bit(y[i]+5))==0&& (sta&bit(y[j]+5))==0  )return false;
            }
            else{
                if( (sta&bit(x[i])) || (sta&bit(x[j])) )continue;
                if(y[i]!=y[j] && ((sta&bit(y[i]+5)) || (sta&bit(y[j]+5)) ))continue;
                return false;
            }
        }
    }
    return true;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    cin>>n;
    string s;
    for(int i=0;i<n;i++){
        cin>>s;
        who(s,i);
    }
    int ans=inf;
    for(int sta=0;sta<(1<<10);sta++){
        //cout<<bitset<11>(sta)<<endl;
        int num=0;
        for(int i=0;i<5;i++){
            if(sta&(1<<i)){
                num++;
            }
            if(sta&(1<<(i+5))){
                num++;
            }
        }
        if(check(sta))ans=min(ans,num);
    }
    cout<<ans<<endl;
    return 0;
}

D.Andrey and Problem(贪心)

题意

你有N个朋友,每个朋友都有百分之a[i]的几率给你出题,你现在只想要一道题,

想知道你选择哪些朋友给只出一题的几率最大,输出最大几率

例如 n=2

a1=0.1 a2=0.2

答案是 0.1×0.8 + 0.9×0.2=0.26

思路

一开始我是直接DP背包的然后发现错了,结果答案直接排序一下,暴力枚举就行了,我也不知道怎么证明...感觉很奇怪

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=5e4+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
double dp[maxn];

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n;
    cin>>n;
    double yes,no;
    for(int i=1;i<=n;i++)cin>>dp[i];
    sort(dp+1,dp+1+n,[](double a,double b){
         return a>b;});
    yes=dp[1],no=1.0-dp[1];
    for(int i=2;i<=n;i++){
        double nowyes,nowno;
        nowyes=dp[i]*(no)+(1-dp[i])*(yes);
        if(nowyes>yes){
            yes=nowyes;
            no=no*(1-dp[i]);
        }
    }
    cout<<fixed<<setprecision(10);
    cout<<yes;
    return 0;
}

E.Artem and Array (模拟栈,贪心)

题意

给你N个数,这N个数相邻,你每次可以删除一个数,然后得到这个数周围两个数的最小值,(如果有一边没有数字只能获得零值)让你求把这N个数全部删除的值

思路

在纸上模拟一下,如果要最优那就是一开始把小的都删除(等于的也要删除),最后留下的都是比较大的,会发现留下的数组是一个先递增再递减的数组,并且最大和第二大的值是相邻的无法取到,所以答案就是前面删除获取的值和后面剩下的数组的前n-2小的值

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n;
ll a[maxn];
ll ans;
ll st[maxn];
int top=0;
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        ll x;
        cin>>x;
        while(top>=2&&st[top-1]>=st[top]&&x>=st[top]){
            ans+=min(st[top-1],x);
            top--;
        }
        st[++top]=x;
    }
    sort(st+1,st+top+1);
    for(int i=1;i<=top-2;i++){
        ans+=st[i];
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/luowentao/p/10436404.html

时间: 2024-09-30 06:52:35

Codeforces Round 253 (Div. 2)的相关文章

Codeforces Round #253 (Div. 2)——Borya and Hanabi

题目连接 题意: n表示有n个卡片,每个卡片有一种颜色和一个数字(共五种不同的颜色和五个不同的数字).事先知道每种卡片有几张,但是不知道具体的位置.问需要几次提示就可以知道所有卡片的位置都在哪里:每次提示可以选择一个颜色或者一个数字,就可以知道含有所选属性的牌有哪些. 分析: 首先明白总情况数不多,只有2^10,所以枚举. 能确定某张牌位置的情况:1)提示了一个属性,而这个属性只有一张牌 2)某个属性有n张牌,知道了n-1张牌的位置 两个提示确定一张牌:必然的,只要存在这张牌,那么两个提示必然可

Codeforces Round #253 (Div. 2) B - Kolya and Tandem Repeat

本题要考虑字符串本身就存在tandem, 如测试用例 aaaaaaaaabbb 3 输出结果应该是8而不是6,因为字符串本身的tanderm时最长的 故要考虑字符串本身的最大的tanderm和添加k个字符后最大的tanderm #include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> using namespace std

Codeforces Round #253 (Div. 2), problem: (B)【字符串匹配】

简易字符串匹配,题意不难 1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 int main(){ 9 int i, j, k, t, n; 10 int num, flag, ans; 11 char a[300]; 12 sc

Codeforces Round #253 (Div. 1) (A, B, C)

Codeforces Round #253 (Div. 1) 题目链接 A:给定一些牌,然后现在要提示一些牌的信息,要求提示最少,使得所有牌可以被分辨出来. 思路:一共2^10种情况,直接暴力枚举,然后对于每种情况去判断,判断的时候只要两两张牌枚举出来判断即可.不得不说CF机子真心强大,2秒限制还是能跑10^8 B:给定n个发生概率,求选出其中一些事件,使得正好有一件发生的概率最大. 思路:贪心,从大到小排序概率,然后一个个概率进来判断有没有更大,有就加入该事件,没有就跳过 C:给定n个数字,要

Codeforces Round #253 (Div. 1)-A,B

A题: 由题意可知,最多翻10次就可以(其实8次就够了),那么我们就用状态压缩表示状态. 对于某种状态,如果某一位为0,那么代表这一位不翻,否则代表这一位翻. 对于某一种翻的状态: 如果牌中有G3,那么就把G和3进行连边.其他的连边类似,不要重边. 对于任意一条边的两个端点,分三种情况讨论: 1,两个端点都翻了,那么很明显,这张牌被表示出来了. 2,两个端点中只有一个端点被翻,那么这个对应的num加1. 3,两个端点都没有被翻,计数器tt加1. 对于任意一种状态: 1,如果计数器tt大于1,那么

Codeforces Round #253 (Div. 2) A. Anton and Letters

题目很简单,只需要注意带空格的输入用getline即可 #include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> using namespace std; int main(){ string str; getline(cin,str); set<char> a; for(int i= 1 ; i < s

Codeforces Round #253 (Div. 2)B(暴力枚举)

就暴力枚举所有起点和终点就行了. 我做这题时想的太多了,最简单的暴力枚举起始点却没想到...应该先想最简单的方法,层层深入. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i