A Permutation
链接:https://ac.nowcoder.com/acm/contest/5675/A
题意:
给定一个质数p,问是否存在一个长度为n-1的数列, =1,
%p或者
%p,存在输出数列,否则输出-1
题解:
暴力,模拟
注意:
不能出现重复的数字
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int a[maxn];
int vis[maxn];
int main()
{
int t,p;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
scanf("%d",&p);
a[1]=1;vis[1]=1;int a1,a2,flag=0;
for(int i=2;i<=p-1;i++)
{
a1=a[i-1]*2%p;
a2=a[i-1]*3%p;
if(!vis[a1])
{
vis[a1]=1;
a[i]=a1;
}
else if(!vis[a2]){
vis[a2]=1;
a[i]=a2;
}
else
{
flag=1;
break;
}
}
if(flag){
printf("-1\n");
continue;
}
for(int i=1;i<=p-1;i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
return 0;
}E Game
链接:https://ac.nowcoder.com/acm/contest/5675/E
题意:
一堆摞在一起的砖头,只能从右往左推,问能够推之后得到的最低的高度
题解:
就是从左边开始的i个前缀和除以i的最小值,(比方说第一个,肯定是最高的高度,接下来第二个,可以挪动,挪到最小的高度,...直到最后一个)
注意:
向下取整
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll a[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int x,ans=0;double sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum+=a[i];
x=ceil(sum/i);
ans=max(ans,x);
}
printf("%d\n",ans);
}
return 0;
}I Tournament
链接:https://ac.nowcoder.com/acm/contest/5675/I
题意:
有n个队伍,现在两两比赛,一共要进行n(n-1)/2场比赛,而每个队伍只需要在他最开始的比赛和最后一场比赛都在场就行,其他的时间可以离开,问所有队伍到场的天数的总和最小是多少
题解:
可以先把队伍分成两部分。前,后
前与前进行比赛
前与后进行比赛(分成两部分,第一部分是前->分散着进行比赛,后->集中。第二部分前->集中(开始渐渐离场),后->分散)
后与后进行比赛
注意:
队伍比赛的顺序尽可能的分散
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll a[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int x,ans=0;double sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum+=a[i];
x=ceil(sum/i);
ans=max(ans,x);
}
printf("%d\n",ans);
}
return 0;
}J Identical Trees
链接:https://ac.nowcoder.com/acm/contest/5675/J
题意:
给定两颗n个节点的树,要修改多少次编号,才能使得他们一样
题解:
从他们的根节点开始搜索,搜到叶节点。由叶节点逐个进行比较,叶节点得到的修改个数然后再继续向上,最后弄出来,,,(好吧,老实说,我看不懂)
注意:
下次再来看看吧,我太low了,只能给代码注释注释了,看懂了的小伙伴可以滴滴我
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
struct rec{
int r1,r2,c;
bool operator <(const rec&n)const {return c>n.c;}
};//自定义排序
int t1[maxn][maxn],t2[maxn][maxn];bool v1[maxn],v2[maxn];
int dfs(int r1,int r2)//表示两方的根节点
{
priority_queue<rec>q;//优先队列
int s1=t1[r1][0],s2=t2[r2][0];//s1,s2表示r1,r2的子节点个数
if(s1!=s2)return -1;//节点个数就不一样,崩
for(int i=1;i<=s1;i++)v1[t1[r1][i]]=false;//让所有的子节点都清空,进行下面的循环操作
for(int i=1;i<=s2;i++)v2[t2[r2][i]]=false;
for(int i=1;i<=s1;i++)
{
for(int j=1;j<=s2;j++)
{
int cc=dfs(t1[r1][i],t2[r2][j]);//去访问r1r2的子节点,得到子节点需要更换的次数
if(cc!=-1)
q.push({t1[r1][i],t2[r2][j],cc});//先从子节点开始访问得到个数,然后慢慢迭代
}
}
int ans=0;
if(r1!=r2)ans++;//表示这两个对应的编号不同,需要变换
int c1=0;
while(!q.empty())
{
rec now=q.top();//先给ans大的子节点标记
q.pop();
if(v1[now.r1]||v2[now.r2])continue;
ans+=now.c;
v1[now.r1]=true;
v2[now.r2]=true;
c1++;
}
if(c1!=s1)return -1;//表示访问的节点少于已知的节点,出现问题
return ans;
}
int main()
{
int n,x;
scanf("%d",&n);
int r1,r2;
for(int i=1;i<=n;i++){
scanf("%d",&x);
t1[x][++t1[x][0]]=i;
r1=(x==0?i:r1);
}
for(int i=1;i<=n;i++){
scanf("%d",&x);
t2[x][++t2[x][0]]=i;
r2=(x==0?i:r2);//得到的是根节点的编号
}
printf("%d",dfs(r1,r2));
return 0;
}
京公网安备 11010502036488号