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

  

posted @ 2020-10-20 22:08  liyongqishiwo  阅读(115)  评论(0编辑  收藏  举报