题解_四月二十六

1.合唱队型:把队伍分成两节,第一节找最长递增子序列,第二节找最长递减子序列,从而找到总的最长队形,即可知道要踢去几人
#include<stdio.h>
int main()
{
	int i,j,k,n,x[101],y[101],t,temp;
	while(scanf("%d",&n)==1)
	{
		t=0;
		for(i=0;i<n;i++)
			scanf("%d",&x[i]);
		for(i=0;i<n;i++)            //以任意位置分开队伍
		{
			temp=0;
			for(j=0;j<101;j++)
				y[j]=240;
			y[0]=y[n]=-1;
			for(j=0;j<i;j++)
			{
				k=0;
				while(x[j]>y[k])
				{
					if(x[j]>y[k]&&x[j]<y[k+1])y[k+1]=x[j];
					k++;
				}
			}
			for(j=i;j>0;j--)if(x[i]>y[j]){temp=j;break;}      //找到递增子序列
			for(j=n-1;j>i;j--)
			{
				k=n;
				while(x[j]>y[k])
				{
					if(x[j]>y[k]&&x[j]<y[k-1])y[k-1]=x[j];
					k--;
				}
			}
			for(j=i+1;j<n;j++)if(x[i]>y[j]){temp+=n-j;break;}   //找到递减子序列
			if(t<temp)t=temp;
		}
		printf("%d\n",n-t-1);
	}
	return 0;
}

2.集合:新鲜的排序,将两个递增序列排在一起,找到两个序列中较小的数排在起来,代码虽短,但是技巧性很强。
#include<stdio.h>
int main()
{
	int n,i,j=1,k=1,x[200000]={0,1},m;
	for(i=2;i<=200000;i++)
	{
		m=2*x[j]+1;
		n=4*x[k]+5;
		if(m>n){x[i]=n;k++;}else{x[i]=m;j++;}           //选择较小的那个排在当前数组后面
	}
	while(scanf("%d",&n)==1)
		printf("%d\n",x[n]);
	return 0;
}


3.Vigenère密码:和上次解密那题相似,找到解密的规律对密文进行操作。明文=密文-密匙+‘A'(或者'a')

#include<stdio.h>
#include<string.h>
int main()
{
    int i,j,t,k;
    char m[1005],c[105];
    while(scanf("%s%s",c,m)==2)
    {
        t=strlen(c);
        for(i=0;i<t;i++)
            if(c[i]<='Z')c[i]-='A';else c[i]-='a';             //把密匙改成ascII码,方便操作
        for(i=0,j=0;i<strlen(m);i++)
        {
            k=m[i]-c[j++];
            if(m[i]>='a')if(k>='a')printf("%c",k);else printf("%c",k+26);    //解密操作,j来记录是否重用密匙
            else if(k>='A')printf("%c",k);else printf("%c",k+26);
            if(j==t)j=0;
        }
        printf("\n");
    }
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值