2017中国大学生程序设计竞赛-哈尔滨站 极少部分题解
2017中国大学生程序设计竞赛-哈尔滨站
F题 Permutation
跟榜签到题
想排列的英文想了半天,结果发现题目不就是吗...
直接STL暴力打表找规律
发现答案形如 1 n 2 n-1 3 n-2 4...
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int T,a[N],n;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int temp=n;
for(int i=1;i<=n/2;i++)
{
a[i*2]=temp--;
}
for(int i=n-n/2;i>=1;i--)
{
a[i*2-1]=temp--;
}
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}
H题 A Simple Stone Game
本来是没准备贴这道题的,但是比赛的时候莫名打错然后自闭了
求\(一个mod使{\sum_{i=1}^{i=n}b_i}\%mod=0 \iff sum\%mod=0\)
显然质因数肯定比因数的解更优,所以只用求出所有质因数然后枚举就行了
注意一下 ans初始化为sum-\(max(a_i)\) 因为如果素数筛不够大的话sum刚好是素数就刚好枚举不到sum这个素数(爆内存)
但是似乎数据没有这个坑?
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,M=3e5+5;
int T,n,a[N],maxn,ss[N],k,b[N];
long long ans,sum;
bool use[M];
vector <int> f;
void pd()
{
use[1]=1;
for(int i=2;i<M-3;i++)
{
if(use[i]==0)
ss[++k]=i;
for(int j=1;j<=k&&ss[j]*i<M-3;j++)
{
use[ss[j]*i]=1;
if(i%ss[j]==0)
break;
}
}
}
int main()
{
scanf("%d",&T);
pd();
while(T--)
{
scanf("%d",&n);
sum=0;
maxn=-1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
maxn=max(a[i],maxn);
}
ans=sum-maxn;
f.clear();
for(int i=1;i<=k&&ss[i]<=sum;i++)
{
if(sum%ss[i]==0)
{
f.push_back(ss[i]);
while(sum%ss[i]==0)
sum/=ss[i];
}
}
for(auto mod:f)
{
for(int i=1;i<=n;i++)
b[i]=a[i]%mod;
sort(b+1,b+n+1);
int posl=1,posr=n;
long long tempans=0;
while(posl<posr)
{
if(b[posl]+b[posr]>mod)
{
tempans=tempans+mod-b[posr];
b[posl]=b[posl]-mod+b[posr];
posr--;
}
else
{
tempans+=b[posl];
b[posr]+=b[posl];
posl++;
}
}
ans=min(ans,tempans);
}
printf("%lld\n",ans);
}
return 0;
}
/*
2
5
1 2 3 4 5
1
2
5
23404 19878 8440 10483 19291
*/
D 题 X-men
题意:
给你一些点,只要存在两点之间距离大于1,就可以移动,每移动一步算1s,两个点总是尽可能的最短时间内相遇|相邻,求最长的时间
虽然两个点距离可能是奇数,但是相邻的时候也相当于相遇所以路程除二,所以不影响"相遇"时间
求最长时间也就是求两点之间的最长距离/2期望都是唬人的
开始想LCA,emmm想多了
还是之间枚举所有点直接BFS算了
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int T,n,m,x,y,tot,a[N],ans;
bool use[N],vis[N];
struct node
{
int pos,step;
};
vector <int> f[N];
queue <node> q;
int bfs(int x,int cnt)
{
while(!q.empty())
q.pop();
memset(vis,0,sizeof(vis));
vis[x]=1;
q.push((node){x,0});
while(!q.empty())
{
node temp=q.front();
q.pop();
if(use[temp.pos]==1)
cnt--;
if(cnt==0)
return temp.step;
for(auto i:f[temp.pos])
{
if(vis[i]==0)
{
vis[i]=1;
q.push((node){i,temp.step+1});
}
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
f[i].clear();
memset(use,0,sizeof(use));
tot=0;
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(use[x]==0)
{
a[++tot]=x;
use[x]=1;
}
}
for(int i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
if(x==y)
continue;
f[x].push_back(y);
f[y].push_back(x);
}
ans=0;
for(int i=1;i<=tot;i++)
{
ans=max(ans,bfs(a[i],tot));
}
printf("%d.00\n",ans/2);
}
return 0;
}
$道路千万条,点赞第一条;阅读不规范,笔者两行泪$