比赛时候傻逼了卡在b上,最后4题,e还没来的及看
总结这套div3还挺简单的,就补完了
standard input/output
standard input/output
standard input/output
standard input/output
Yet Another Division Into Teams
standard input/output
standard input/output
1 s, 256 MB x280
A
水题if判断
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long a,b,n,s;
scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&s);
long long num=min(s/n,a);
num=s-num*n;
if(num<=b)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
}
B 写复杂了,开始想的模拟每次把队列中最小的元素移动到最靠前的位置
其实直接循环然后标记一下当前位置即可
#include<bits/stdc++.h>
using namespace std;
int a[105];
int pos[105];
int vis[105];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
vector<int>a;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int tmp;
scanf("%d",&tmp);
a.push_back(tmp);
pos[tmp]=i;
}
int cur=0;
for(int i=1;i<=n;i++)
{
if(vis[i]!=0) continue;
if(pos[i]>cur)
{
for(int j=pos[i];j>cur;j--)
{
swap(a[j],a[j-1]);
}
for(int j=pos[i]-1;j>=cur;j--)
{
vis[a[j]]++;
}
cur=pos[i];
}
else if(i==a[cur]) cur++,vis[i]++;
}
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
}
C
直接贪心就行了,不知道过的人怎么这么少
#include<bits/stdc++.h>
using namespace std;
int len[10005];
int main()
{
int n,m,d;
scanf("%d%d%d",&n,&m,&d);
int sum=0;
for(int i=1; i<=m; i++)
{
scanf("%d",&len[i]);
sum+=len[i];
}
int num=n-sum;
if(num>(d-1)*(m+1))
{
printf("NO\n");
}
else
{
printf("YES\n");
for(int i=1; i<=m; i++)
{
int tmp=d-1;
while(tmp&&num)
{
printf("0 ");
num--;
tmp--;
}
while(len[i])
{
printf("%d ",i);
len[i]--;
}
}
while(num)
{
printf("0 ");
num--;
}
}
}
D 直接贪心把0移动到最前面
#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n,k;
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%01d",&a[i]);
}
int num=1;
int last1=0;
int last2=0;
for(int i=1;i<=n;i++)
{
last2=i;
if(a[i]==0)
{
if(k>i-num)
{
k-=i-num;
num++;
}
else
{
last1=i-k;
break;
}
}
}
//cout<<num<<" "<<last1<<" "<<last2<<endl;
for(int i=1;i<=n;i++)
{
if(i<num) printf("0");
else if(i==last1) printf("0");
else if(i<=last2) printf("1");
else printf("%d",a[i]);
}
printf("\n");
}
}
E dp+路径回溯
反向思考看能够减去的最大值
只要遍历3个即可因为别的可以转移过来
#include<bits/stdc++.h>
using namespace std;
struct node
{
int id;
int num;
int col;
friend bool operator < (node p,node q)
{
return p.num<q.num;
}
}a[200005];
int dp[200005];
bool cmp(node p,node q)
{
return p.id<q.id;
}
int main()
{
vector<int>ve;
memset(dp,0,sizeof(dp));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].num);
a[i].id=i;
}
sort(a+1,a+1+n);
int MAX=0;
int pos=0;
for(int i=4;i<=n-2;i++)
{
for(int j=3;j<=5;j++)
{
if(i>j)
{
dp[i]=max(dp[i-j]+a[i].num-a[i-1].num,dp[i]);
}
}
if(dp[i]>MAX)
{
MAX=dp[i];
pos=i;
}
}
while(pos>3)
{
int flag=0;
for(int i=3;i<=5;i++)
{
if(dp[pos]-dp[pos-i]==a[pos].num-a[pos-1].num)
{
flag=1;
ve.push_back(pos);
pos=pos-i;
break;
}
}
if(flag==0) break;
}
sort(ve.begin(),ve.end());
int tmp=1;
int cur=0;
// cout<<ve[0]<<" "<<ve[1]<<endl;
for(int i=1;i<=n;i++)
{
if(cur>=ve.size()||i!=ve[cur]) a[i].col=tmp;
else
{
cur++;
tmp++;
a[i].col=tmp;
}
}
printf("%d %d\n",a[n].num-a[1].num-MAX,ve.size()+1);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
printf("%d ",a[i].col);
}
}
F 每次交换两个数我们可以得到任意一个序列
如果没有同种元素,两个序列逆序对的差的绝对值变化都是偶数 所以判断逆序对即可
#include<bits/stdc++.h>
using namespace std;
int viss[100];
int vist[100];
char s[200005];
char t[200005];
int n;
void solve()
{
memset(viss,0,sizeof(viss));
memset(vist,0,sizeof(vist));
for(int i=1; s[i]; i++)
{
viss[s[i]-'a']++;
vist[t[i]-'a']++;
}
for(int i=0; i<26; i++)
{
if(viss[i]!=vist[i])
{
printf("NO\n");
return;
}
}
for(int i=0; i<26; i++)
{
if(viss[i]>1)
{
printf("YES\n");
return ;
}
}
int cnt1=0;
int cnt2=0;
for(int i=1; i<=n; i++)
{
for(int j=i+1;j<=n;j++)
{
if(s[i]>s[j]) cnt1++;
if(t[i]>t[j]) cnt2++;
}
}
if(cnt1%2==cnt2%2)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
scanf("%d",&n);
scanf("%s",s+1);
scanf("%s",t+1);
solve();
}
}