由于开学了,一般晚上就不打cf了(太晚了,寝室不太适合打),而且赛后也懒得vp,有时候会在图书馆口胡题目,然后回寝室补一补,不过我也写得太久了吧,很多细节疯狂wa
A - Copy-paste
不难发现排序后答案就是 ⌊ k − a 2 a 1 ⌋ + ⌊ k − a 3 a 1 ⌋ + ⌊ k − a 4 a 1 ⌋ + ⋯ + ⌊ k − a n a 1 ⌋ \lfloor \frac{k-a_2}{a_1}\rfloor+\lfloor \frac{k-a_3}{a_1}\rfloor+\lfloor \frac{k-a_4}{a_1}\rfloor+\dots+\lfloor \frac{k-a_n}{a_1}\rfloor ⌊a1k−a2⌋+⌊a1k−a3⌋+⌊a1k−a4⌋+⋯+⌊a1k−an⌋
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int a[N];
int n,k;
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
ll res=0;
for(int i=2;i<=n;i++) res+=(k-a[i])/a[1];
cout<<res<<'\n';
}
return 0;
}
B - Two Arrays
贪心分组,排序后双指针扫描。
注意: a i = a j a_i=a_j ai=aj并且 a i + a j = T a_i+a_j=T ai+aj=T的情况,平均分组。
这个方法写了很久,当然也可以用map
直接记录,不需要双指针而且也比较友好。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int,int> pii;
const int N=100010;
pii a[N];
int n,m;
int pos[N];
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].first;
a[i].second=i;
pos[i]=-1;
}
sort(a+1,a+1+n);
for(int i=1,j=n;i<j;i++)
{
while(j>i&&a[i].first>m-a[j].first) pos[a[j--].second]=0;
while(j>i&&a[i].first==m-a[j].first)
{
if(a[i].first==a[j].first)
{
pos[a[i++].second]=0;
pos[a[j--].second]=1;
}
else pos[a[j--].second]=1;
}
if(j>=i) pos[a[i].second]=0;
}
for(int i=1;i<=n;i++)
{
if(pos[i]!=-1)
cout<<pos[i]<<' ';
else
cout<<0<<' ';
}
cout<<'\n';
}
return 0;
}
C - k-Amazing Numbers
预处理pos[i]
表示值是i
数组出现的位置,可以用vector
存储,然后如果每两个值之间的最大距离是len
(注意开头和结尾)那么i
就可以作为长度为len
的一个子串的答案。然后随便搞搞就行了
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=300010;
int a[N];
int n;
vector<int> pos[N];
int len[N];
int ans[N];
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
pos[i].clear();
len[i]=0;
ans[i]=-1;
}
for(int i=1;i<=n;i++)
{
cin>>a[i];
pos[a[i]].push_back(i);
}
for(int i=1;i<=n;i++)
{
int m=pos[i].size();
for(int j=1;j<m;j++)
len[i]=max(len[i],pos[i][j]-pos[i][j-1]);
if(m)
{
len[i]=max(len[i],pos[i][0]);
len[i]=max(len[i],n+1-pos[i][m-1]);
}
}
for(int i=1;i<=n;i++)
if(ans[len[i]]==-1) ans[len[i]]=i;
int now=-1;
for(int i=1;i<=n;i++)
{
if(ans[i]==-1) cout<<now<<' ';
else
{
if(now==-1) now=ans[i];
else now=min(ans[i],now);
cout<<now<<' ';
}
}
cout<<'\n';
}
return 0;
}
D - Make Them Equal
首先先把所有值搞到 a 1 a_1 a1上,最多需要 2 ( n − 1 ) 2(n-1) 2(n−1)次操作:如果 a i % i = 0 a_i\%i=0 ai%i=0一次操作就可以否则需要先用 a 1 a_1 a1去把 a i a_i ai调整成 i i i的倍数,然后再需要一次操作。
然后直接用 a 1 a_1 a1把所有值搞成平均数即可最多 n − 1 n-1 n−1次操作。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int a[N],n;
struct node
{
int l,r,x;
};
vector<node> ans;
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
ans.clear();
cin>>n;
int s=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s+=a[i];
}
if(s%n)
{
cout<<-1<<'\n';
continue;
}
s/=n;
for(int i=2;i<=n;i++)
{
int p=a[i]%i;
if(p)
{
a[1]+=a[i];
ans.push_back({
1,i,i-p});
ans.push_back({
i,1,a[i]/i+1});
a[i]=0;
}
else
{
a[1]+=a[i];
ans.push_back({
i,1,a[i]/i});
}
}
for(int i=2;i<=n;i++)
ans.push_back({
1,i,s});
cout<<ans.size()<<'\n';
for(auto t:ans) cout<<t.l<<' '<<t.r<<' '<<t.x<<'\n';
}
return 0;
}
E - XOR Inverse
待补,本来在图书馆都想好咋做了,然后回来补题时候发现不咋对。。。
要加油哦~