A. Kids Seating
题意
- 链接:A. Kids Seating
- 在1到4n中选n个数出来使得它们两两之间不互质且两个数之间不能是整除关系(比如a跟b a不能整除b且b不能整除a)
解题思路
满足条件1两两之间不互质 的是 1到4n中所有的偶数共2n个
满足条件2两个数之间不能是整除关系 的是 2n到4n间的所有数共2n个
将两个集合取交集得n个满足题目条件的数 即 从2n开始取n个偶数
代码
#include<stdio.h>
using namespace std;
typedef long long ll;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int cnt=0;
while(cnt<n-1)
{
printf("%d ",4*n-cnt*2);
cnt++;
}
printf("%d\n",4*n-cnt*2);
}
return 0;
}
B. Saving the City
题意
- 链接:B. Saving the City
- 给你一串01字符串,1表示有炸弹,0表示没有,将一个炸弹引爆(如果相邻处有炸弹也会被引爆)需要花费a,在0处安放一个炸弹需要花费b,问使字符串变成全0的最小花费
解题思路
- 贪心
- 把第一个连续的1子串引爆,然后枚举每一个连续的1子串,看是 直接引爆该子串的花费a 还是 把该串与上一个连续的1子串间的0放上炸弹与上一子串一起引爆的花费b*cnt(cnt即两子串间0的个数) 哪个小取哪个
代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
char s[maxn];
int t,n,aa,bb;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&aa,&bb);
scanf("%s",s+1);
int len=strlen(s+1),ans=0,pos,cnt=1003;
for(int i=1;i<=len;i++)
if(s[i]=='1')
{
pos=i;break;
}
while(pos<=len)
{
if(s[pos]=='1')
{
ans+=min(aa,bb*cnt);
cnt=0;
while(s[pos]=='1')pos++;
}
else if(s[pos]=='0')
{
cnt++;pos++;
}
}
printf("%d\n",ans);
}
return 0;
}
D. Extreme Subtraction
题意
- 链接:D. Extreme Subtraction
- 有一个长为n的序列,每次可以把前任意k个数或者后任意k个数全减去1,你可以操作任意次,问能否使序列变成全0
解题思路
- 从后往前处理,如果能处理成一个非递减序列则符合要求
- 如果a[i+1]>a[i]就把i+1到n的数全减到a[i],如果不能进行操作则说明不能
代码
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
int t,n,a[30003];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int maxn=a[n],dis,f=1;
for(int i=n-1;i>=1;i--)
{
if(a[i+1]>a[i])
{
dis=a[i+1]-a[i];
if(dis<=maxn)maxn-=dis;
else{
f=0;
break;
}
}
}
if(f)printf("YES\n");
else printf("NO\n");
}
return 0;
}