QFNU-ACM 2020.10.16 Trating and ACM 实验室2020.10.17天梯赛练习*3
B - Power Sequence
题意:就是把给定的数进行交换或者分配使得变成等比数列。
题解:进行枚举并判断注意数的范围。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
const LL inf=1e18;
LL a[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n;cin>>n;
for(LL i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
LL ans=inf;
for(LL c=1;c<=1000000; c++)
{
LL cur=1;
LL now=0;
bool flag=1;
for(LL i=0;i<n;i++)
{
if(cur>=1000000000000){flag=0;break;}
now+=fabs(a[i]-cur);
cur*=c;
}
if(flag) ans=min(ans,now);
}
cout<<ans<<endl;
return 0;
}
D - Drinks Choosing
题意:给定n和k表示n个人和k种饮料,和n个人喜好的饮料类型,一个饮料可以分为2种味道的饮料,问最多可以使得多少人喝到自己喜欢的饮料。
题解:先把他们喜欢喝的饮料统计一下,如果数量大于等于2就进行++和(n+1)/2--,因为大于等于2就刚刚好够了,而不等于2就会浪费,把剩下的数量加起来。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
int p;
cin>>n>>k;
int a[10010]={0};
for(int i=0;i<n;i++){
cin>>p;
a[p]++;
}
//for(int i=1;i<=k;i++){
// cout<<a[i]<<endl;
//}
int num=(n+1)/2;
int sum=0;
for(int i=1;i<=k;i++){
while(a[i]>=2&&num>0){
a[i]=a[i]-2;
num--;
sum=sum+2;
}
}
cout<<sum+num<<endl;
}
7-9 小字辈 (25分)
题意:给定n个数,表示这个数是他的编号的数的父母,如果这个数为-1为这个家族中的最高辈分,问最小辈分是多少,哪几个数是最小辈分。
题解:把编号和这个数存到一个二维数组中,并找到最高的辈分是多少,然后从最高辈分开始大法师搜索(dfs),依次搜索,如果搜索到的辈分大于maxn就把maxn为现在的辈分,然后把存到ans数组中的数清0,重新存入,表示他们这些数不是最小的辈分,如果辈分==maxn表示辈分是最低,就把辈分相同的数进行存入。然后排序输出就行。
#include<bits/stdc++.h>
#include<vector>
using namespace std;
vector<int>v[500000],ans;//ans存最小辈分
vector<int>::iterator it;
int maxn=-1;
void dfs(int n,int deep){
for(int i=0;i<v[n].size();i++){
dfs(v[n][i],deep+1);//对下一辈的进行搜索判断有无子代
}
if(deep>maxn){//如果有更小的子代,就把数组清空重新存最小的一代
maxn=deep;
ans.clear();
ans.push_back(n);
}
else if(maxn==deep){//辈分相同且最小,存进数组去。
ans.push_back(n);
}
}
int main(){
int n,p;
int pos;
cin>>n;
for(int i=1;i<=n;i++){
cin>>p;
if(p==-1){
pos=i;
continue;
}
v[p].push_back(i);//属于p的儿子存进数组
}
dfs(pos,1);//从老祖宗开始搜索
sort(ans.begin(),ans.end());
cout<<maxn<<endl;
cout<<*ans.begin();
for(it=ans.begin()+1;it!=ans.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
7-12 深入虎穴 (25分)
题意:根据给定的点找到最远的那个点。
题解:题目没有给定入口在哪,所以需要根据各个点进行判断,然后找到最远的那个点就行。
代码:
#include <bits/stdc++.h>
using namespace std;
#define N 100005
vector<int> v[N];
bool visit[N]={false};
int main()
{
int n,k,t;
cin>>n;
for(int i=1; i<=n; i++){
cin>>k;
while(k--){
cin>>t;
visit[t]=true;
v[i].push_back(t);
}
}
int start,res=1;
for(start=1; start<=n; start++)
if(!visit[start])
break;
queue<int> q;
q.push(start);
while(!q.empty()){
t=q.front();
for(auto i:v[t])
q.push(i);
q.pop();
if(q.size()==1)
res=q.front();
}
cout<<res;
}

浙公网安备 33010602011771号