Codeforces Round #659 (Div. 2)

5 篇文章 0 订阅
2 篇文章 0 订阅

比赛链接:https://codeforces.com/contest/1384

A.Common Prefixes

题意:

给你n个数表示数组a,让你输出n+1个字符串,使第i+1个字符串和第i个字符串有a[i]位前缀相同。

AC

#include<bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const LL N = 1e5 + 10;
int a[105];
char s[105];
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]);
        }
        for(int i=1;i<=60;i++)
        {
            s[i-1]='a';
            printf("a");
        }
        printf("\n");
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=a[i];j++)
            {
                printf("%c",s[j-1]);
            }
            for(int j=a[i]+1;j<=60;j++)
            {
                printf("%c",(s[j-1]+1)%26+'a');
                s[j-1]=(s[j-1]+1)%26+'a';
            }
            printf("\n");
        }
    }
    return 0;
}

B2. Koa and the Beach (Hard Version)

小吐槽:这道题放在B的位置上是真的恶心(是B题该有的水准吗?),比赛最后时间过了B1,B1改B2多打了个break,赛后一发过

题意:

一个人在s的位置上,要到t的位置,在s和t之间,有n米路,第i米位置有a[i]的水深,给你了l,表示这个人不能在水深超过l的水里,不然会被淹死,然后又给你了k,表示潮汐,p[[数组表示潮汐,长度为2k,p[0,1,2,3,…k-1,k,k-1,k-2,…1];
假设当时时间为t,那么第i位置的水深就为d[i]=a[i]+p[t%2k];要保证人走到第i的位置的时候,d[i]<=l;
问你,这个人能不能走到t。

思路

我当时是这样想的,我们可以贪心一下,我们最开始走到一个位置,那么我们这个位置的保持潮汐下落的最大值,因为潮汐是有规律的,一凹一凸。手绘了一张假图,帮助理解

在这里插入图片描述
就这样往后判断就行。
复杂度也不是很高

/*
 * @沉着,冷静!: 噗,这你都信!
 * @LastEditors: HANGNAG
 * @LastEditTime: 2020-07-25 10:02:07
 * @FilePath: \undefinedc:\Users\13099\Desktop\niuke\main.cpp
 */
#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const LL N = 1e5 + 10;
int a[300005];
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n, k, l;
        scanf("%d%d%d", &n, &k, &l);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
        }
        int flog = 0, ku;
        int num = -k;
        for (int i = 1; i <= n; i++)
        {
            int u = l - a[i];
            ku = 0;
            if (u < 0)
            {
                flog = 1;
                break;
            }
            if (num < 0)
            {
                if (abs(num) > u)
                {
                    num = -u;
                    ku = 1;
                    
                }
                else
                {
                        num++;
                        ku = 1;
                        
                }
            }
            else
            {
                if (num + 1 <= u)
                {
                    num++;
                    ku = 1;
                    
                }
            }
            //            for(int j=1;j<=k;j++)
            //            {
            //               if(abs(num+j)<=u)
            //               {
            //                    num=num+j;
            //
            //               }
            //            }
            if (num >= k || u >= k)
            {
                num = -k;
            }
            //printf("%d*",num);
            if (ku == 0)
            {
                flog = 1;
                break;
            }
        }
        if (flog)
        {
            printf("No\n");
        }
        else
        {
            printf("Yes\n");
        }
    }
    return 0;
}

C. String Transformation 1

题意

题意很简单,就是给你两个字符串a,b,然后你可以选择a里面相同的字符,然后把他们变大,问最少几次这样操作可以使a字符串转变为b字符串。如果不可能输出-1.

思路

因为题目中告诉你,最多20个,而且只能增加,那么我们就每次枚举当前要改变的字符,把他们加到这些选中的数的对应b字符串中的最小值,以此类推,操作一次ans+1,最后输出ans,如果出现相同位置上,最开始,b[i]<a[i],因为只能增加,所以不可能,就输出-1。

AC

#include<bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const LL N = 1e5 + 10;
int a[N];
int b[N];
char s1[N],s2[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        scanf("%s %s",s1,s2);
        int flog=0;
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            a[i]=s1[i-1]-'a'+1;
            b[i]=s2[i-1]-'a'+1;
            if(b[i]<a[i])
            {
                flog=1;
                break;
            }
        }
        if(flog)
        {
            printf("-1\n");
        }
        else
        {
            int minn=1000;
            int ff=0;
            for(int i=1;i<=20;i++)
            {
                minn=1000;
                ff=0;
                for(int j=1;j<=n;j++)
                {
                    if(a[j]==i&&b[j]>a[j])
                    {
                       ff=1;
                        minn=min(minn,b[j]-a[j]);
                    }
                }
                for(int j=1;j<=n;j++)
                {
                    if(a[j]==i)
                    {
                        a[j]+=minn;
                    }
                }
                ans+=ff;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

D. GameGame

题意:

两个人玩游戏,给你一些数,每个人的初始分数都是0,然后两个人可以依次选择一些数,假设当前K的分数为x,然后K选择了y,然后现在的分数就是x^y(x异或y),现在是K先走,问你K最后的情况,是WIN(赢),LOSE(输),DRAW(平局)

思路

异或我们都知道,相同为1,不能为0,那么我们现在只需要找到最高一位,数目为奇数的位置,(因为10000>01111,只要最高位掌握在手,还怕后面的?),找数目为奇数的主要是因为两个人拿,分脏不均,总会有一个有,一个没有。究竟是谁有,谁没有,还是要看这奇数的数量和不含这一位二进制数的个数。
1,每一位二进制数的书面都是偶数,平局
2.K赢的条件:
假设现在第i位的二进制数目不同,数目为num[i];
K拿了(num[i]/2+1)个,num[i]/2+1是个奇数,那么就是说我们K拿了这些之后,无论你怎么拿,我都有最高位这些在手。
还有一种就是K拿了(num[i]/2+1)个,但是这个数是个偶数,但是现在假设还有u个没有这一二进制位的数,就相当于废数,如果k%2==1,我们开头拿一个废数充数,然后情况就完全反转了,我们就可以放心的拿了,他要是也拿废数,我们就再拿一个废数,因为只要k%2=1,一定可以保持我们拿的废数多,让他变成先手,必输手。
(语言如果描述不清楚的地方,可以自己推推,也可以留言解决。)

AC

/*
 * @沉着,冷静!: 噗,这你都信!
 * @LastEditors: HANGNAG
 * @LastEditTime: 2020-07-25 20:49:19
 * @FilePath: \undefinedc:\Users\13099\Desktop\workspace\worksapce\main.cpp
 */
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;
int num[50];
int bit(int x)
{
  int tot=0;
  while(x)
  {
    if(x&1)
    {
      num[tot]++;
    }
    x/=2;
    tot++;
  }
}
int main()
{
  int t;
  scanf("%d", &t);
  while (t--)
  {
    memset(num,0,sizeof(num));
    int n;
    scanf("%d", &n);
    int x;
    for (int i = 1; i <= n; i++)
    {
      scanf("%d", &x);
      bit(x);
    }
    int flog=0;
    for(int i=32;i>=0;i--)
    {
      if(num[i]%2)
      {
        if(((num[i]+1)/2%2==0&&(n-num[i])%2==1)||(num[i]+1)/2%2==1)
        {
          printf("WIN\n");
        }
        else
        {
          printf("LOSE\n");
        }
        flog=1;
        break;

      }
    }
    if(!flog){
      printf("DRAW\n");
    }
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值