A. Chips Moving
题意:有一个
- 将第
个数向左或向右移动 个位置(即用 或 替换当前坐标 ); - 将第
个数向左或向右移动 个位置(即用 或 替换当前坐标 ),花费 个硬币。
注意,所有数可以移动到任意整数坐标位置,包括负数和
你的任务是找到一个最小的花费硬币数,使所有
解析:考虑奇偶性,很明显,一个数可以移动到任意同奇偶的位置,花费
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,sum1,sum2;
int x[110];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x[i]);
if(x[i]&1)
sum1++;
else
sum2++;
}
printf("%d",min(sum1,sum2));
return 0;
}
B. Bad Prices
题意:给你一个
解析:两种解法,第一种倒序遍历,记录当前已遍历的最小值,如果比遍历到的新数小,那么新数就是一个不好的数,统计加
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int t,n,a[151010],b[151010],q[151010],tree[151010];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
tree[i]+=val;
}
int query(int x)
{
int sum=0;
for(int i=x;i;i-=lowbit(i))
sum+=tree[i];
return sum;
}
int main()
{
scanf("%d",&t);
while(t--)
{
int ans=0;
memset(tree,0,sizeof(tree));
memset(a,0,sizeof(a));
scanf("%d",&n);
int now=0,cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
cnt=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
q[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
for(int i=n;i>=1;i--)
{
update(q[i],1);
now=query(q[i]-1);
if(now)
ans++;
}
printf("%d\n",ans);
}
return 0;
}
C. Book Reading
题意:有一本
解析:相加得到的只与尾数相关,且尾数是循环出现的,我们只用预处理
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int q;
long long n,m;
int len[10]={1,10,5,10,5,2,5,10,5,10};
int sum[10]={0,45,20,45,20,5,20,45,20,45};
int main()
{
scanf("%d",&q);
while(q--)
{
long long ans=0,now=0;
scanf("%lld%lld",&n,&m);
now=n/m;
ans=now/len[m%10]*sum[m%10];
int q=now%len[m%10],r=m%10,s=r;
for(int i=1;i<=q;i++)
{
ans+=s;
s=(s+r)%10;
}
printf("%lld\n",ans);
}
return 0;
}
D. Equalizing by Division
题意:有一个
解析:直接把序列内的所有数预处理,用
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
int n,k;
int a[201010];
vector<int> s[201010];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
int x=a[i];
s[x].push_back(0);
for(int j=1;x;j++)
{
x/=2;
s[x].push_back(j);
}
}
for(int i=0;i<=2e5;i++)
sort(s[i].begin(),s[i].end());
int ans=2e9;
for(int i=0;i<=2e5;i++)
{
int len=s[i].size();
if(len>=k)
{
int r=0;
for(int j=0;j<k;j++)
r+=s[i][j];
ans=min(ans,r);
}
}
printf("%d",ans);
return 0;
}
E. Two Small Strings
题意:给你两个长度为
解析:首先肯定存在这样的字符串。分类讨论,如果两个字符串的两个字母都不同,则只用输出类似于这种样式的字符串:
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,book[4][4];
char s[3],t[3];
int main()
{
scanf("%d",&n);
scanf("%s%s",s+1,t+1);
printf("YES\n");
if(s[1]!=s[2]&&t[1]!=t[2])
{
memset(book,0,sizeof(book));
book[s[1]-'a'+1][s[2]-'a'+1]=1;
book[t[1]-'a'+1][t[2]-'a'+1]=1;
int a,b,c;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
{
if(i==j||j==k||i==k)
continue;
if(book[i][j]==0&&book[j][k]==0)
{
a=i;
b=j;
c=k;
break;
}
}
for(int i=1;i<=n;i++)
printf("%c",a+'a'-1);
for(int i=1;i<=n;i++)
printf("%c",b+'a'-1);
for(int i=1;i<=n;i++)
printf("%c",c+'a'-1);
return 0;
}
else if(s[1]==s[2]&&t[1]==t[2])
{
for(int i=1;i<=n;i++)
printf("abc");
return 0;
}
else if(s[1]==s[2]&&t[1]!=t[2])
{
memset(book,0,sizeof(book));
book[t[1]-'a'+1][t[2]-'a'+1]=1;
int a,b,c;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
{
if(i==j||j==k||i==k)
continue;
if(book[i][j]==0&&book[j][k]==0&&book[k][i]==0)
{
a=i;
b=j;
c=k;
break;
}
}
for(int i=1;i<=n;i++)
printf("%c%c%c",a+'a'-1,b+'a'-1,c+'a'-1);
return 0;
}
else if(t[1]==t[2]&&s[1]!=s[2])
{
book[s[1]-'a'+1][s[2]-'a'+1]=1;
int a,b,c;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
{
if(i==j||j==k||i==k)
continue;
if(book[i][j]==0&&book[j][k]==0&&book[k][i]==0)
{
a=i;
b=j;
c=k;
break;
}
}
for(int i=1;i<=n;i++)
printf("%c%c%c",a+'a'-1,b+'a'-1,c+'a'-1);
return 0;
}
return 0;
}