前言:前几天晚上打了一场Div1+2后终于上蓝,为了纪念,这周就写这一场的题解了。
A.Changing Volume
水题,贪心。优先移动5格,然后2格,最后1格。
#include<bits/stdc++.h>
using namespace std;
int T,x,y;
int main()
{
cin>>T;
while(T--)
{
cin>>x>>y;
if(y<x)swap(x,y);
if(x==y)cout<<0<<"\n";
else
{
int tt=(y-x)/5;
cout<<(tt+(y-x-tt*5)/2+(y-x-tt*5)%2)<<"\n";
}
}
}
B.Fridge Lockers
水题。当点数不小于边数时,若要使每个点至少连两个边,只能形成一个大环。
#include<bits/stdc++.h>
using namespace std;
int T,n,m,a;
int main()
{
cin>>T;
while(T--)
{
int sum=0;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a,sum+=a;
if(n==2||m<n)
{
cout<<-1<<"\n";
continue;
}
else cout<<sum*2<<"\n";
for(int i=0;i<n;i++)
cout<<(i)%n+1<<" "<<(i+1)%n+1<<"\n";
}
}
C.League of Leesins
观察发现当 时, 和 只存在于一个三元组, 和 只存在于两个三元组,其他元素都存在于三个三元组。所以可以记录每个数字的出现次数和所属的三元组,然后从出现次数为 的数字所载的三元组开始删除(出现次数–),然后寻找下一个出现 次的数,删除顺序就是答案。时间复杂度
注意删到最后会出现一个次数为 的三元组,此时应根据其最初出现次数由大到小放进答案,否则亲身试验会WA2(
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int T,n,m,a[N],vis[N],pre[N],v[N];
int t[N][3];
vector<int> G[N],ans;
bool cmp(int a,int b)
{
return pre[a]>pre[b];
}
void dfs(int x)
{
if(vis[x]==1)
{
ans.push_back(x);
for(int j=0;j<G[x].size();j++)
{
if(v[G[x][j]])continue;
int* tmp=t[G[x][j]];
v[G[x][j]]=1;
if(vis[tmp[0]]==1&&vis[tmp[1]]==1&&vis[tmp[2]]==1)
{
ans.pop_back();
sort(tmp,tmp+3,cmp);
for(int k=0;k<3;k++)
ans.push_back(tmp[k]);
for(int k=0;k<n;k++)cout<<ans[k]<<" ";
exit(0);
}
for(int i=0;i<3;i++)vis[tmp[i]]--;
for(int i=0;i<3;i++)dfs(tmp[i]);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n-2;i++)
for(int j=0;j<3;j++)
{
cin>>t[i][j];
vis[t[i][j]]++;
pre[t[i][j]]++;
G[t[i][j]].push_back(i);
}
for(int i=1;i<=n;i++)
dfs(i);
}
D.Feeding Chicken
首先算出 即为每种颜色最低分配的 的数量,我们可以从上到下 型贪心涂色。对于前 个 来说,每 个 的颜色都是相同的;在这之后,每 个 涂一种颜色即可。时间复杂度
#include<bits/stdc++.h>
using namespace std;
int T,n,m,k;
char a[111][111];
vector<char> c;
int main()
{
for(char i='a';i<='z';i++)c.push_back(i),c.push_back(i-'a'+'A');
for(char i='0';i<='9';i++)c.push_back(i);
scanf("%d",&T);
while(T--)
{
int cnt=1,num=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%s",a[i]+1);
for(int j=1;j<=m;j++)cnt+=(a[i][j]=='R');
}
for(int i=1;i<=n;i++)
if(i&1)
for(int j=1;j<=m;j++)
{
if(a[i][j]=='R')num++;
a[i][j]=c[num*k/cnt];
}
else
for(int j=m;j>=1;j--)
{
if(a[i][j]=='R')num++;
a[i][j]=c[num*k/cnt];
}
for(int i=1;i<=n;i++)
printf("%s\n",a[i]+1);
}
}
E1&2.Send Boxes to Alice
令 表示所给数列前 项之和,若使所有盒子里的数都能被大于 的数 整除,则 必是 的质因子。因此,我们可以预处理出所有可能的素因子 。
对于每一个 ,设 位置之前都满足 ( 能被 整除),则对于第 个位置来说,若要满足题目条件,只能将第 个位置的数减少(从 向后分)或增加(从 之后向 分),对答案的贡献即为 。枚举所有可能的 并线性时间内处理答案取最小值即可。时间复杂度 , 为 的素因子个数,为 之内的常数。
#include <bits/stdc++.h>
#define ll long long
#define N 1000010
using namespace std;
int n;
ll a[N],sum[N],tmp,ans=(1LL<<60);
vector<ll> fac;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],sum[i]=sum[i-1]+a[i];
tmp=sum[n];
if(tmp==1)
{
cout<<-1;
return 0;
}
for(ll i=2;i*i<=tmp;i++)
if(tmp%i==0)
{
while(tmp%i==0)tmp/=i;
fac.push_back(i);
}
if(tmp>1)fac.push_back(tmp);
for(auto it:fac)
{
ll s=0;
for(int i=1;i<n;i++)
s+=min(sum[i]%it,it-sum[i]%it);
ans=min(ans,s);
}
cout<<ans;
}
F.Point Ordering
未完待续