AtCoder Beginner Contest 336

A、Long Loong

题意:先打印L,再打印n个o,再打印ng

n=int(input())

print("L",end="")
for i in range(n):
    print("o",end="")
print("ng")

B、CTZ

题意:给一个数,将这个数转换为2进制,计算二进制结果后边有多少个0

用lowbit解决,lowbit 一下可以得到2进制数最后一位1的10进制数

n=int(input())

x=int(n&(-n))#lowbit
res=0
if x==1:
    print(res)
else:
    while x:
        x//=2
        res+=1
    print(res-1)

补充一个bin()函数

n=int(input())
x=bin(n)#可以将10进制转为2进制 bin(8)=0b1000 前面会多一个0b
y=x[::-1]#逆序               bin(10)=0b1010

print(y.find('1'))

 

C、Even Digits

 寻找第几个好的数,好的数定义为:每个数位上的数都为偶数

通过打表前20个好的数,可以发现,本质上是一个5进制的数,每5个数进一次位

下边是c++代码,比赛过程中,写完代码一直发现总是与标准答案多进了一位,调了很长时间

写的像依托答辩

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

int o[20];
int d[10]={0,2,4,6,8,8};
signed main()
{
	
	o[1]=5;
	for(int i=2;i<=19;i++)
	{
		o[i]=o[i-1]*5;
	}
	int n;
	cin>>n;
	
	int f=0;
	int res=0;
	int f1=0;
	for(int i=18;i>=1;i--)
	{
//		cout<<"i=="<<i<<"   n=="<<n<<endl;
		int x=n/o[i];
		if(x==0&&f==1)
		{
			res=res*10;

		 } 
		else if(x!=0)
		{			
//			cout<<d[x];
			if(f1==0)
			{
				res=d[x];
				f1=1;
			}
			else res=res*10+d[x];
			f=1;
			n=n%o[i];
		}
	}
	res=res*10+d[n];
	string str1=to_string(res);
	int xx=str1.length();
	for(int i=xx-1;i>=0;i--)
	{
		if(str1[i]>='2')
		{
			str1[i]=str1[i]-2;
			break;
		}
		else
		{
			str1[i]='8';
		}
	}
	for(int i=0;i<xx;i++)
	{
		if(i==0&&str1[i]=='0'&&xx!=1) continue;
		else cout<<str1[i]<<"";
	}
	cout<<endl;
	return 0;
}

下边是改进后的代码,发现上边的非常冗余,只需要n在最开始减1就行,因为要对5取余数,那么循环就应该是0~4,所以n应该减1

n=int(input())

d=[0,2,4,6,8]
x=5
a=[]
for i in range(18):
    a.append(x)
    x*=5
n-=1
f=0
#print(d[0],d[1])

for i in range(17,-1,-1):
   y=int(n//a[i])
   if y==0 and f==1:print("0",end="")
   elif y>0:
       print(d[y],end="")
       f=1
       n=int(n%a[i])
print(d[n])

D、 Pyramid 

题意:求最长的金字塔

可以执行一下操作:

令一个数减1,或者删除最前一个数,或者删除最后边一个数

维护一个从左到右的序列和一个从右到左的序列

金字塔的左半边:x[i]=min(x[i-1]+1,a[i])

左半边可以形成的条件是从左到右依次增加,且差值为1,最理性的是1,2,3,4,5,,,

此时需要考虑原序列的影响,假如在3的位置原序列为1,那么就只能再从1开始,那么4的位置是2,以此类推,所以推论就是 x[i]=min(x[i-1]+1,a[i])

即使最开始原序列为 5 6 7 8 3 2 1,那么我们总可以将前4个一直减1,得到1 2 3 4 3 2 1 

同理右半边的推论为:y[i]=min(y[i+1]+1,a[i])

最终答案就是res=max(res,min(x[i],y[i]))

n=int(input())

a=list(map(int,input().split()))
x=[0 for i in range(n+1)]
y=[0 for i in range(n+2)]

for i in range(1,n+1):
    x[i]=min(x[i-1]+1,a[i-1])
for i in range(n,0,-1):
    y[i]=min(y[i+1]+1,a[i-1])
res=0
for i in range(1,n+1):
    res=max(res,min(x[i],y[i]))
print(res)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值