CodeForces 138A 题解

CodeForces - 138A   Literature Lesson 

题意:每组第一行给出两个数字n,k。接下来是4*n行,一共n小节,如果一个小节的4个单词从倒数第k个元音开始到单词结尾都一样 那这个小节就是aaaa型 ;第一个和第三个一样或第二个和第四个一样就是abab型;还有aabb行 abba型 ;其它就不是韵文。如果给出的所有小节都有同样的类型(aaaa可以看成是abba aabb abab的特殊情况 ) 就输出这首诗的类型 否则输出NO。

思路:这道题难点在于题目的理解,如果题目理解了,那这道题就很简单,把所有的情况考虑一遍就可以了。代码如下。

AC代码:

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

typedef long long ll;

const int N=10100;
char s[5][N];
char w[5][N];
int n,m;
int q[N];
int main()
{
    scanf("%d%d",&n,&m);
    int flag=0,v=0;
    for(int i=1; i<=n; i++)
    {
        scanf("%s%s%s%s",s[1],s[2],s[3],s[4]);
        if(flag==1)continue;
        for(int j=1; j<=4; j++)
        {
            int d=strlen(s[j]),num=0,t=0,tag=0;
            for(int k=d-1; k>=0; k--)
            {
                char c=s[j][k];
                if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')//元音字母的判断
                {
                    num++;
                    w[j][t++]=c;
                    if(num==m){tag=1;break;}
                }
                else w[j][t++]=c;
            }
            if(tag==0)flag=1;
            w[j][t]='\0';
        }
        if(flag==1)continue;
        int h[6]={0},ans=0;
        if(strcmp(w[1],w[2])==0)h[0]=1,ans++;
        if(strcmp(w[3],w[4])==0)h[1]=1,ans++;
        if(strcmp(w[1],w[3])==0)h[2]=1,ans++;
        if(strcmp(w[2],w[4])==0)h[3]=1,ans++;
        if(strcmp(w[2],w[3])==0)h[4]=1,ans++;
        if(strcmp(w[1],w[4])==0)h[5]=1,ans++;
        if(ans==6)q[++v]=1;//aaaa
        else if(h[0]==1&&h[1]==1)q[++v]=2;//aabb
        else if(h[2]==1&&h[3]==1)q[++v]=3;//abab
        else if(h[4]==1&&h[5]==1)q[++v]=4;//abba
    }
    int book[5]={0};
    for(int i=1;i<=v;i++)book[q[i]]++;
    if(flag)printf("NO");
    else if(book[1]==n)printf("aaaa\n");
    else if(book[1]+book[2]==n)printf("aabb\n");
    else if(book[1]+book[3]==n)printf("abab\n");
    else if(book[1]+book[4]==n)printf("abba\n");
    else printf("NO\n");
}

CodeForces - 1384B1   Koa and the Beach (Easy Version) 

题意:n米的海和一个在n+1的点的岛组成。一个人测量了从海岸线1,2,…,n米到岛屿的海的深度,这个海有潮汐,潮汐的强度取决于参数k,参数k影响了海的深度,对于从时间t=0开始,前k秒,每过一秒导致所有海的深度+1,然后再k秒,潮汐每过一秒导致所有海的深度都 -1。这个过程不断地持续着,从0开始我们可以定义一个数组p=[0,1,2,...,k−2,k−1,k,k−1,k−2,...,2,1],长度为2k,在时间t,第i米的深度为di+p[tmodk]。这个人从海岸线开始游到岛屿,每一秒,他可以前进或者呆在原地,如果当且深度>l,那么这个人就会被淹死。求这个人如果可以到达岛屿输出YES,否则输出NO。

思路:这道题可以通过dp来做。dp [ i ] [ j ]当这个人到达第i片海域的时间为j秒这个状态是通过的
dp[ i ] [ j ] 可以由 dp[ i ] [ j - 1](上一秒在第 i 片海域选择不移动)和 dp[ i - 1 ] [ j - 1 ](上一秒在 i-1 片海域选择移动)两个状态状态转移达到,只要两者有一个状态是合法的,那么dp[i][j]就是可到达的。然后我们还要证明dp[i][j]状态本身是否合法,即判断当前状态的深度是否大于l。最后我们只需要找dp[n][j]的状态中是否有合法的即可。

AC代码:

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

typedef long long ll;

const int N=110;

#define mem(a,b) memset(a,b,sizeof(a))

int T,n,k,l;
int d[N],p[2*N];
int dp[N][2*N*N];

void init()//初始化
{
    for(int i=0;i<=k;i++)p[i]=i;//预处理
    for(int i=1;i<k;i++)p[k+i]=k-i;
    mem(dp,0);
    for(int i=0;i<2*k;i++)dp[0][i]=1;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&k,&l);
        init();
        for(int i=1;i<=n;i++)scanf("%d",&d[i]);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=2*n*k;j++)
            {
                dp[i][j]=max(dp[i][j-1],dp[i-1][j-1]);
                if(p[j%(2*k)]+d[i]>l)dp[i][j]=0;
            }
        }
        int flag=0;
        for(int i=0;i<2*n*k;i++)
        if(dp[n][i]){flag=1;break;}
        if(flag)printf("Yes\n");
        else printf("No\n");
    }
}

 CodeForces - 1384C  String Transformation 1 

题意:给出两个等长的字串A,B.通过变换,要求A能变成B.变换规则如下:可将A中的一个字母或多个相同的字母变成字典序更大的字母。A若能成功变成B.输出最小变换次数。如不行,输出-1。

思路:并查集简单模板。

AC代码:

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

const int N=100010;
int T,n,ans;
int f[30];
char a[N],b[N];

int getf(int v)
{
    if(f[v]==v)return v;
    else return f[v]=getf(f[v]);
}

void merge1(int x,int y)
{
    int t1=getf(x);
    int t2=getf(y);
    if(t1!=t2)
    {
        ans++;
        f[t2]=t1;
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        ans=0;
        int flag=0;
        for(int i=1;i<=28;i++)f[i]=i;
        scanf("%s%s",a,b);
        for(int i=0;i<n;i++)
            if(a[i]>b[i]){flag=1;break;}
        if(flag){printf("-1\n");continue;}
        for(int i=0;i<n;i++)
            merge1(a[i]-'a'+1,b[i]-'a'+1);
        printf("%d\n",ans);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值