zoukankan      html  css  js  c++  java
  • 2018沈阳集训day1

    问题 A: 马克的字符串

    时间限制: 1 Sec  内存限制: 256 MB

    题目描述

    定义一个字符串满足'MK'性质当且仅当它修改其中不超过k个字符后是回文串。给你一个字符串,问它有多少非空子串满足'MK'性质。

    输入

    输入的第一行包含一个字符串s

    输入的第二行包含一个整数k

    输出

    输出的第一行包含一个整数,为满足'MK'性质的字串数量。

    样例输入

    Aab
    1
    

    样例输出

    6
    

    提示

    【样例说明】

    每一个字串都是回文串或修改一个字母后是回文串

    【数据规模与约定】

    对于30%的数据:k=0


    对于100% 的数据:字符串长度 1<=l<=100,0<=k<=50

    题解:n^3暴力,开始跑了个manacher,结果WA了,至今迷

    #include<bits/stdc++.h>
    using namespace std;
    char str[208];
    int k; 
    bool check(int i, int j){
        int cnt = 0;
        while(i <= j){
            if(str[i]  != str[j])cnt ++;
            if(cnt > k)return 0;
            i++, j--;
        }
        return 1;
    }
    int main(){
        scanf("%s", str);
        scanf("%d", &k);
        int ans = 0;
        int len = strlen(str); 
        for(int i = 0; i < len; i++)
            for(int j = i; j < len; j++)
                ans += check(i, j); 
        printf("%d",ans);
    }
    View Code

    问题 B: 马克家的书

    时间限制: 1 Sec  内存限制: 256 MB

    题目描述

    马克家收藏了一套书,这套书叫《OIER故事集》,这套书有n本,每本书有一个编号,从1号到n号。

    马克把这些书按照编号从小到大,从上往下摞成一摞。马克对这套书很珍视,不允许其他人动。

    有一天一格到马克家玩,马克因为和妹子约会,就让一格自己呆在家里。一格因为对这套书非常好奇,偷偷的看了一下,结果发现书中竟然有ljscommonc的故事。一格看的入了迷,结果把一摞书的顺序弄乱了。

    眼看着马克就要回来了,一格需要把书恢复到原状,由于每本书都比较重,所以一格能做的操作是把一本书从书堆中抽出来,然后把这本书放到书堆的顶部。

    给你打乱的书的顺序,你能帮一格算算最少需要几次上述操作,才能恢复书的顺序。

    输入

    第一行包含一格正整数T(T<=10),表示数据组数。

    对于每组数据,第一行为一格整数n

    接下来的一行有n个用空格分开的正整数,表示一格打乱后的书的顺序,从上到下。

    输出

    对于每组数据,输出一行一个整数,表示一格最少经过几次操作才能恢复书的顺序

    样例输入

    2
    4
    4 1 2 3
    5
    1 2 3 4 5
    

    样例输出

    3
    0
    

    提示

    【样例说明】

    对于第一组数据,我们先把3号书放在最上面,接着操作2号书,最后操作1号书,(4123)—(3412)—(2341)—(1234)这样就有序了

    对于第二组数据,已经有序就不需要挪了。

    【数据规模与约定】

    对于 50% 的数据满足 n<=10

    对于 80%的数据满足 n<=1000


    对于 100% 的数据满足 n<=100000

      题解:智力题,从后往前扫,递减序列,其他的最少移动一次

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 100005;
    int a[maxn];
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            int p = n, cnt = 0;
            for(int i = n; i >= 1; i--)
                if(a[i] == p)p--, cnt++;
            printf("%d
    ",n - cnt);
        }
         
    }
    View Code

    问题 C: 马克的幸运数

    时间限制: 1 Sec  内存限制: 256 MB

    题目描述

    马克和同学们玩卡牌游戏。一共有n张卡牌,每张卡牌上有一个数Ai,每次可以从中选出k张卡牌。一种选取方案的幸运数为这k张卡牌上数的异或和。马克想知道所有选取方案的幸运数之和除以998244353的余数。

    输入

    第一行有两个整数n和k。

    第二行有n个整数,表示序列A。

    输出

    一行,一个整数,表示答案。

    样例输入

    3 2
    1 2 3
    

    样例输出

    6
    

    提示

    【样例说明】

     

    样例1幸运值之和为(1 ⊕ 2) + (1 ⊕ 3) + (2 ⊕ 3) = 6

     

     


    【样例输入2】


    10 5


    123 456 789 987 654 321 101 202 303 404


    【样例输出2】


    130776


     


    【数据规模与约定】


    对于30%的数据满足,1<=n<=20


    对于另30%的数据满足,1<=n<=100,0<Ai<=1024


    对于80%的数据满足,1<=n<=2000


    对于100%的数据满足,1<=n<=100000,0<Ai<2^31,1<=k<=n

     题解:亦或和拆位,统计每位有1的个数,只有选奇数个才有贡献,然后方枚举选1多少个,选0多少个,乘法原理,注意特判不要超过k

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 100005;
    #define ll long long
    ll a[maxn], fac[maxn], infac[maxn];
    const ll p = 998244353;
    ll exgcd(ll a, ll b, ll &x, ll &y){
        if(b == 0){
            x = 1; y = 0; return a;
        }
        ll x0, y0;
        ll d = exgcd(b, a % b, x0, y0);
        x = y0;
        y = x0 - (a / b ) * y0; 
        return d;
    }
    ll inv(ll a){
        ll x, y;
        exgcd(a, p, x, y);
        return (x % p + p) % p;
    }
    int main(){
        int n, k;
        fac[0] = 1;
        infac[0]= 1;
        ll ans = 0;
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++){
            scanf("%lld", &a[i]);
            fac[i] = fac[i-1] * i % p;
            infac[i] = inv(fac[i]);
        }
        long long an=1;
        for(int i = 0; i <= 31; i++){
            int sum = 0;
            for(int j = 1; j <= n; j++)
                if(a[j] & (1<<i) )sum++;  
            int siz = min(k, sum);
            for(int j = 1; j <= siz; j+=2)
                if (k - j <= n-sum )
                    ans = ( ans +  ( (1ll<<i) % p * (fac[sum] * infac[j] % p * infac[sum-j] % p ) % p * (fac[n - sum] * infac[n - sum - k + j] % p * infac[k - j] % p) ) )% p;
        }
        printf("%lld
    ", ans);
    }
    View Code

    问题 D: 马克的达人秀

    时间限制: 1 Sec  内存限制: 256 MB

    题目描述

    马克要带着他的N个oier,方便起见编号为1…N,到oi展览会上去,参加每年的达人秀!他的第i个oier体重为wi,才艺水平为ti,两者都是整数。在到达时,马克就被今年达人秀的新规则吓到了:

    (一)参加比赛的一组oier必须总重量至少为W(这是为了确保是强大的队伍在比赛,而不仅是强大的某个oier),并且

    (二)总才艺值与总重量的比值最大的一组获得胜利。

    马克注意到他的所有oier的总重量不小于W,所以他能够派出符合规则(一)的队伍。帮助他确定这样的队伍中能够达到的最佳的才艺与重量的比值。

    输入

    输入的第一行包含N和W。下面N行,每行用两个整数wi和ti描述了一个oier。

    输出

    请求出马克用一组总重量最少为W的oier最大可能达到的总才艺值与总重量的比值。

    如果你的答案是A,输出1000*A向下取整的值,以使得输出是整数

    (当问题中的数不是一个整数的时候,向下取整操作在向下舍入到整数的时候去除所有小数部分)。

    样例输入

    3 15
    20 21
    10 11
    30 31
    

    样例输出

    1066
    

    提示

    在这个例子中,总体来看最佳的才艺与重量的比值应该是仅用一个才艺值为11、重量为10的oier,但是由于我们需要至少15单位的重量,最优解最终为使用这头奶牛加上才艺值为21、重量为20的oier。这样的话才艺与重量的比值为(11+21)/(10+20)=32/30=1.0666666…,乘以1000向下取整之后得到1066。

     

    【数据规模与约定】


    对于20%的数据满足,1<=n<=20


    对于40%的数据满足,1<=n<=50,输出答案保证小于23333


    对于100%的数据满足,1≤N≤250,1≤W≤1000,1≤wi≤10^6,1≤ti≤10^3


    保证数据有梯度

     题解:dp,01背包, f[i][j]表示达到才艺值为i最少花的体力, 答案就在dp[0~sum][w] (w >W)中

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 300, maxm = 300005, inf = 1000000008;
    int N, W;
    const double eps = 1e-6;
    struct cow{
        int t, w; double val;
    }c[maxn];
    int dp[2][maxm];
    int main(){
        scanf("%d%d", &N, &W);
        int sum = 0; double ans = 0;
        for(int i = 1; i <= N; i++)
            scanf("%d%d", &c[i].w, &c[i].t), sum += c[i].t;
        int u = 0;
        for(int i = 1; i <= sum; i++) dp[u][i] = inf;
        dp[0][0] = 0;
        for(int i = 1; i <= N; i++){
            u ^= 1;
            for(int j = 0; j <= sum; j++)dp[u][j] = dp[u^1][j];
            for(int j = c[i].t; j <= sum; j++)dp[u][j] = min(dp[u][j], dp[u^1][j - c[i].t] + c[i].w);
            /*for(int j = 0; j <= sum; j++)if(dp[u][j] != inf){
                printf("i = %d j = %d dp = %d
    ",i,j,dp[u][j]);
            }*/
        }
        for(int i = 0; i <= sum; i++)
            if(dp[u][i] >= W) ans = max(ans, 1.0 * i / dp[u][i]);
        printf("%d
    ", (int) floor(ans*1000));
    }
    View Code

    第一天考崩了,差距巨大,后面怎么也追不上去,奠定我在联训悲惨的基调

  • 相关阅读:
    机器语言与汇编语言的关系
    环境变量
    .NET程序运行过程
    【转】计算机组成原理
    将大型 Page Blob 的页范围进行分段
    价格更低、SLA 更强的全新 Azure SQL 数据库服务等级将于 9 月正式发布
    把二元查找树转换成排序的双向链表
    初识C++
    Linux企业级项目实践之网络爬虫(25)——管理源代码之SVN
    Linux企业级项目实践之网络爬虫(24)——定制规则扩展为垂直爬虫
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9166158.html
Copyright © 2011-2022 走看看