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; }