2020-8-10 个人赛补题

链接: link.
判断是否能改造成回文串,直接暴力解决,我们设一个num[]数组存放各字母出现的次数,如果个数为奇数的字母的数量大于一则能不能构成回文串,反之可以。我们还需要按最小字典序输出,采取正序和倒序各遍历一次,每次输出num[i]/2个,如果存在个数为奇数的字母,我们在第一次正序遍历后再输出一个该字母。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>

using namespace std;

char str[1010];
int num[30];

int main()
{
    int t;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            getchar();
            memset(num,0,sizeof(num));
            scanf("%s",str);
            int len = strlen(str);
            for(int i=0; i<len; i++)
            {
                num[str[i]-'a']++;//统计数量
            }
            int sum = 0;
            for(int i=0; i<26; i++)
            {
                if(num[i]%2!=0)//找出奇数个字母的数量
                    sum++;
            }
            if(sum>1)//大于一则直接输出
            {
                cout<<"impossible"<<endl;
                continue;
            }
            char ch;
            for(int i=0; i<26; i++)//正向遍历
            {
                if(num[i]&1)
                    ch = 'a'+i;//存放奇数个数量的字母
                if(num[i]!=0)
                {
                    for(int j=0; j<num[i]/2; j++)
                    {
                        printf("%c",'a'+i);
                    }
                }
            }
            if(sum==1)
                printf("%c",ch);//第一次循环后输出一次
            for(int i=25; i>=0; i--)//反向遍历
            {
                if(num[i]!=0)
                {
                    for(int j=0; j<num[i]/2; j++)
                    {
                        printf("%c",i+'a');
                    }
                }
            }
            printf("\n");
        }
    }
    return 0;
}

链接: link.
我们设一个标记数组,每当我们输入一组数据时,我们把在这区间中没有标记的格子数量统计下来,并把这些格子标记,这样就避免了重复统计。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>

using namespace std;

int Map[110][110];

int main()
{
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int I,J,K;
        int sum = 0;//统计格子数量
        memset(Map,0,sizeof(Map));//初始化
        for(int i=0; i<n; i++)
        {
            cin>>I>>J>>K;
            for(int k=0; k<=K-1; k++)//给坐标范围是[0,k],则中间格子的数量为0~k-1个
            {
                for(int j=I; j<=J-1; j++)//同上
                {
                    if(Map[k][j]==0)
                    {
                        sum++;
                        Map[k][j]=1;
                    }
                }
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}

链接: link.
采取BFS解决

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n,m;
struct node
{
    int x;
    int y;
} que[10010];

int flag;
int d[8][2]= {{-1,0},{1,0},{0,-2},{0,2},{-1,-2},{-1,2},{1,-2},{1,2}};//因为字母之间存在空格所以左右移动都是2

void BFS(char Map[55][55],int x,int y)
{
    int head = 0;
    int tail = 0;
    //入队
    que[tail].x = x;
    que[tail++].y = y;
    
    int x1,y1,i;
    while(head!=tail)
    {
        //出队
        x1 = que[head].x;
        y1 = que[head++].y;
        
        if(Map[x1][y1]=='e')//找到'e'就输出
        {
            flag = 1;
            printf("Cutie Pie!\n");
            break;
        }
        for(i=0; i<8; i++)
        {
            if(x1+d[i][0]>=0&&x1+d[i][0]<n&&y1+d[i][1]>=0&&y1+d[i][1]<2*m-1)//注意范围
            {
                if(Map[x1][y1]=='p')//找到'p',往下看若为'i'就入队
                {
                    if(Map[x1+d[i][0]][y1+d[i][1]]=='i')
                    {
                        que[tail].x=x1+d[i][0];
                        que[tail++].y=y1+d[i][1];
                    }
                }
                if(Map[x1][y1]=='i')//找到'i',往下看若为'e'则入队
                {
                    if(Map[x1+d[i][0]][y1+d[i][1]]=='e')
                    {
                        que[tail].x=x1+d[i][0];
                        que[tail++].y=y1+d[i][1];
                    }
                }
            }
        }
    }
}
int main()
{
    int t,i,j;
    char Map[55][55];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        getchar();
        for(i=0; i<n; i++)
            gets(Map[i]);
        flag = 0;
        for(i=0; i<n; i++)
        {
            for(j=0; j<2*m-1; j++)//注意字母间有空格
            {
                flag = 0;
                if(Map[i][j]=='p')
                {
                    BFS(Map,i,j);
                    if(flag)
                        break;
                }
            }
            if(flag)
                break;
        }
        if(flag==0)
            printf("Sorry Man\n");
    }
    return 0;
}

链接: link.
找出一个上升子序列,且相邻元素直接相差1

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;

int dp[20010];

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        memset(dp,0,sizeof(dp));
        int cnt = 0;
        int num;
        for(int i=0;i<n;i++)
        {
            cin>>num;
            dp[num] = max(dp[num],dp[num-1]+1);
            cnt = max(cnt,dp[num]);
        }
        cout<<cnt<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值