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;
}
很简单,共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;
}