我是 FSTer,打个 div.3 居然
A. Payment Without Change
题意:给你
解析:模拟即可,注意爆 long long,还有要分情况讨论。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int q;
long long a,b,n,s;
int main()
{
scanf("%d",&q);
while(q--)
{
scanf("%lld%lld%lld%lld",&a,&b,&n,&s);
if(a*n+b<s)
{
printf("NO\n");
continue;
}
long long r=s/n;
if(r<=a)
{
if(b>=s%n)
printf("YES\n");
else
printf("NO\n");
}
else
{
if(b>=s-a*n)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
B. Minimize the Permutation
题意:
解析:暴力搜索,如果前面有比他大的就交换,同时标记,当所有的都被标记完或者已经是最小字典序时就结束循环,输出。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int t,q,n,sum;
int s[110];
int vis[110];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
memset(vis,0,sizeof(vis));
bool flag=1;
while(flag)
{
flag=0;
for(int i=n-1;i>=1;i--)
if(s[i]>s[i+1]&&vis[i]==0)
{
vis[i]=1;
swap(s[i],s[i+1]);
flag=1;
}
}
for(int i=1;i<=n;i++)
printf("%d ",s[i]);
printf("\n");
}
return 0;
}
C. Platforms Jumping
题意:一条河流长度为
解析:贪心,尽量把木板往自己能走到,且在其能放到最后位置前面,尽量往后放,稍微处理一下即可。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,d;
int c[1010],ans[3010];
int sum[1010];
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=m;i++)
{
scanf("%d",&c[i]);
sum[i]=sum[i-1]+c[i];
}
int now=0;
for(int i=1;i<=m;i++)
{
for(int j=min(now+d,n-(sum[m]-sum[i])-c[i]+1);j<=min(now+d,n-(sum[m]-sum[i])-c[i]+1)+c[i]-1;j++)
ans[j]=i;
now=min(now+d,n-(sum[m]-sum[i])-c[i]+1)+c[i]-1;
}
if(now+d>=n+1)
{
printf("YES\n");
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
}
else
printf("NO\n");
return 0;
}
D. Binary String Minimizing
题意:给你
解析:很像
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
long long q,n,k;
char s[1010100];
int main()
{
scanf("%lld",&q);
while(q--)
{
memset(s,0,sizeof(s));
scanf("%lld%lld",&n,&k);
scanf("\n%s",s+1);
int len=strlen(s+1);
for(int i=1,pos=1;i<=len&&k!=0;i++)
if(s[i]=='0')
{
if(i-pos<=k)
{
k-=(i-pos);
swap(s[pos],s[i]);
pos++;
}
else
{
pos=i-k;
swap(s[pos],s[i]);
k=0;
}
}
printf("%s\n",s+1);
}
return 0;
}
E. Yet Another Division Into Teams
题意:给你
解析:DP。
设
同时设立一个数组
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
long long n;
long long ans[201010];
long long f[201010],num,k[201010];
struct node
{
long long x;
long long id;
}t[201010];
long long cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&t[i].x);
t[i].id=i;
}
sort(t+1,t+n+1,cmp);
memset(f,0x3f,sizeof(f));
f[1]=0;
for(int i=1;i<=n;i++)
for(int j=3;j<=5;j++)
if(f[i]+t[i+j-1].x-t[i].x<f[i+j])
{
f[i+j]=f[i]+t[i+j-1].x-t[i].x;
ans[i+j]=i;
}
long long p=n+1;
while(ans[p])
{
num++;
for(int i=ans[p];i<p;i++)
k[t[i].id]=num;
p=ans[p];
}
printf("%lld %lld\n",f[n+1],num);
for(int i=1;i<=n;i++)
printf("%lld ",k[i]);
return 0;
}
F. Equalizing Two Strings
题意:给定两个长度均为
解析:首先比较 NO;
然后如果
然后剩下的情况,和明显反转后,两个字符串的逆序对数量之差的奇偶性是不会变的,所以一开始统计好两个字符串的逆序对,然后判断逆序对数量之差是不是偶数,如果是就可行。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int q,n;
char s[201010],t[201010];
int a[101010],b[101010];
int sum1,sum2;
int main()
{
scanf("%d",&q);
while(q--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int flag=0,sum1=0,sum2=0;
scanf("%d\n",&n);
scanf("%s%s",s+1,t+1);
for(int i=1;i<=n;i++)
{
a[s[i]-'a'+1]++;
b[t[i]-'a'+1]++;
for(int j=s[i]-'a'+1;j<=26;j++)
sum1+=a[j];
for(int j=t[i]-'a'+1;j<=26;j++)
sum2+=b[j];
}
sort(s+1,s+n+1);
sort(t+1,t+n+1);
for(int i=1;i<=n;i++)
if(s[i]!=t[i])
{
printf("NO\n");
flag=1;
break;
}
if(flag)
continue;
for(int i=2;i<=n;i++)
if(s[i]==s[i-1])
{
printf("YES\n");
flag=1;
break;
}
if(flag)
continue;
if((sum1-sum2)&1)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}