13/03/31第四周周赛解题报告

A. Roma and Changing Signs

乍一看此题还挺简单,结果WA了两次,还是要思考一下的(多次change可以作用在一个数上)


代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
	int n,k,i,j,sum1=0,sum=0;
	int a[100001];
	cin>>n>>k;
	for(i=0;i<n;i++)
	{
		cin>>a[i];
	}
	int i1=0;
	while(a[i1]<0)
	{
		a[i1]=(-1*a[i1]);
		sum1++;
		i1++;
		if(i1==n)
			break;
		if(sum1==k)
			break;
	}
	//cout<<a[2]<<endl;
	sort(a,a+n);
	if(sum1==k)
	{
		for(i=0;i<n;i++)
		{
			sum+=a[i];
		}
	}
	else
	{
		if((k-sum1)%2!=0)
			a[0]*=-1;
		for(i=0;i<n;i++)
			sum+=a[i];
			
	}
	cout<<sum<<endl;
	return 0;
}

B. Maxim and Discounts

这道题主要是要理解题目意思,写代码还是挺简单的。选择时第二行当然选最小的(设为m),然后将第四行的数从大到小排序

依次买m件拿2件进行下去

input

2             //选择优惠的方式有几种

2 3          //可以选择买两件再免费拿两件,也可以买三件免费拿两件  

5

50 50 50 50 50

output

150


代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int m,int n)
{
	return m>n;
}
int main()
{
	int m,n,a[100001],b[100001];
	int i,j,min=100001,sum=0;
	cin>>m;
	for(i=0;i<m;i++)
	{
		cin>>a[i];
		min=min>a[i]?a[i]:min;
		//cout<<min<<endl;
	}
	cin>>n;
	for(j=0;j<n;j++)
	{
		cin>>b[j];
	}
	sort(b,b+n,cmp);
	i=0;
	while(i<n)
	{
		j=0;
		while(j<min&&i<n)
		{
			sum+=b[i++];
			j++;
			//cout<<sum<<endl;
		}
		i+=2;
	}
	cout<<sum<<endl;
	return 0;
}


D. Squares

很简单,共m个正方形,所求坐标点要位于n(n<=m)个正方形中(位于n+1个不符合题意)


G. Roadside Trees (Simplified Edition)

比较简单,就不再复制代码。


H. Escape from Stones

其实不必推理计算,只要找到规律很简单,从左向右依次输出字符"r"对应的球号,再从右向左依次输出字符“l"对应球号即可。


I. Good Sequences

这道题是查了别人代码后,理解着写的,思路的确不易想。

扫描到序列中某个元素时,能不能将它加到之前的序列的末尾,只要看它与之前序列的最后一个元素是不是有公因子就行了,我们用b[i]表示末尾数包含因子i的最长好序列的长度。因此,先将扫描到的数进行因式分解,然后再看看各个因子中的最大的b[i]值,将最大值加1,就是扫描这个数之后,最长的好序列的长度。


代码

#include<iostream>
using namespace std;
int a[110000],b[110000];
int main()
{
	int N,num,i,j,res=1;
	cin>>N;
	for(i=0;i<N;i++)
	{
		cin>>num;
		int l=0,mx=0;     //l统计num因数个数,mx为输入此num后最长好序列长度
		for(j=2;j*j<=num;j++)     //因式分解
		{
			if((num%j)==0)
			{
				a[l++]=j;
				if(b[j]+1>mx)
					mx=b[j]+1;
				while((num%j)==0)
					num/=j;
			}
		}
		if(num>1)
		{
			a[l++]=num;
			if(b[num]+1>mx)
				mx=b[num]+1;
		}
		for(j=0;j<l;j++)
			b[a[j]]=mx;
		if(res<mx)
			res=mx;
	}
	cout<<res<<endl;
	return 0;
}




 




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值