zoukankan      html  css  js  c++  java
  • Codeforces Round #636 (Div. 3)

    A. Candies

    题意:当k>1时输出满足题中所给数列的x值

    解题思路:等比数列得(2^k-1)x=n,枚举k值即可、

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    ll t,n;
    
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>n;
    		ll k=3;
    		while(1){
    			if(n%k==0){
    				cout<<n/k<<endl;
    				break;
    			}
    			k=k*2+1;
    		}
    	}
    
    	return 0;
    }
    

    B. Balanced Array

    题意:构建一个长度为n的序列,前n/2全为偶数,后半部分全为奇数,且前后两部分相等

    解题思路:当n/2为奇数时,前后两部分和奇偶不同,显然不成立,所以n/2为偶数,其他数从小到大排,最后一个数特别构造即可。

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    ll t,n;
    
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>n;
    		ll k=n/2;
    		if(k&1) puts("NO");
    		else {
    			puts("YES");
    			for(int i=2,j=1;j<=k;i+=2,j++){
    				cout<<i<<' ';
    			}
    			for(int i=1,j=1;j<k;i+=2,j++){
    				cout<<i<<' ';
    			}
    			cout<<(n-1)+k<<endl;
    		}
    	}
    
    	return 0;
    }
    

    C. Alternating Subsequence

    题意:在序列中找到最长的奇偶相间的子序列,并且该子序列在最长序列中值最大

    思路:首先长度优先,其次在每段长度相同的序列中取最大值

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;
    ll t,n;
    ll a[N];
    
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>n;
    		for(int i=0;i<n;i++) cin>>a[i];
    		ll tmp=a[0],ans=0;
    		for(int i=1;i<n;i++){
    			if(tmp*a[i]<0){
    				ans+=tmp;
    				tmp=a[i];
    			}
    			else{
    				tmp=max(tmp,a[i]);
    			}
    		}
    		cout<<ans+tmp<<endl;
    	}
    
    	return 0;
    }
    

    D. Constant Palindrome Sum

    题意:对序列中的元素可以用[1,k]中的数来替换,使1~n/2的所有i都有a[i]+a[n-i+1]=x且x值相等

    解题思路:可以假设对于每个x值都需要n次替换,而a[i]+a[n-i+1]取值范围在[2,2*k],计算每对替换一次能得到的最大值最小值;

    因此对于x值介于最大值最小值之间的只需替换一次,对于其他范围需要替换两次,这时我们可以运用差分将最大值最小值之间的x值
    替换的次数都减1,而对于不用变换就能得到的也需要减1

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N = 2e5+100;
    ll a[N],cnt[N*2],sub[N*2];
    ll t,n,k;
    
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>n>>k;
    		for(int i=1;i<=n;i++) cin>>a[i];
    		for(int i=2;i<=2*k;i++) cnt[i]=n,sub[i]=0;//每一对都初始化为2次,初始化差分数组
    		for(int i=1;i<=n/2;i++){
    			ll x=a[i],y=a[n-i+1];
    			ll mi=min(x,y)+1,mx=max(x,y)+k;
    			cnt[x+y]--;//不用变换的值减1
    			sub[mi]--;sub[mx+1]++;//对区间[mi,mx]之间的x值都减1
    		}
    		ll ans=0x3f3f3f3f;
    		for(int i=2;i<=2*k;i++){
    			sub[i]+=sub[i-1];//前缀和
    			cnt[i]+=sub[i];
    			ans=min(ans,cnt[i]);
    		}
    		cout<<ans<<'
    ';
    	}
    
    	return 0;
    }
    

    E. Weights Distributing

    题意:找到a->b->c的最短花费

    解题思路:找中间点a->x->b->x->c,可以看出b->x这条边计算两次,所以它的权值应该最小。

        从1~n枚举x,然后计算a,b,c到x点的边数,最后找最小值即可
    

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N = 2e5+100,INF=0x3f3f3f3f;
    ll p[N],sum[N];
    int t,n,m,a,b,c;
    vector<int>g[N];
    
    void bfs(int x,vector<int>&d){
    	d[x]=0;
    	queue<int>q;
    	q.push(x);
    	while(!q.empty()){
    		int p=q.front();
    		q.pop();
    		for(int i=0;i<g[p].size();i++){
    			int v=g[p][i];
    			if(d[v]==INF){
    				d[v]=d[p]+1;
    				q.push(v);
    			}
    		}
    	}
    }
    
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>n>>m>>a>>b>>c;
    		for(int i=1;i<=n;i++) g[i].clear();
    		for(int i=1;i<=m;i++) cin>>p[i];
    		sort(p+1,p+m+1);
    		for(int i=0;i<m;i++){
    			int x,y;
    			cin>>x>>y;
    			g[x].push_back(y);
    			g[y].push_back(x);
    		}
    		vector<int>da(n+1,INF),db(n+1,INF),dc(n+1,INF);
    		bfs(a,da);bfs(b,db);bfs(c,dc);//da表示a到每个点的边数
    		memset(sum,0,sizeof(sum));
    		for(int i=1;i<=m;i++){//前i条边的和
    			sum[i]=sum[i-1]+p[i];
    		}
    		ll ans=1e18;
    		for(int i=1;i<=n;i++){
    //			cout<<da[i]+db[i]+dc[i]<<endl;
    			if(da[i]+db[i]+dc[i]<=m){
    				ans=min(ans,sum[db[i]]+sum[da[i]+db[i]+dc[i]]);
    			}
    		}
    		cout<<ans<<'
    ';
    	}
    
    	return 0;
    }
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    关键字static在C和C++中的区别
    C指针声明解读之左右法则
    各大公司面试题集锦
    C++的const和static的用法
    C++11常用特性总结
    C++多态下的访问修饰符
    #define 宏实现函数功能可能存在的问题
    Qt读写Json
    C/C++ 内存与指针
    C++ delete仍可访问的问题
  • 原文地址:https://www.cnblogs.com/voids5/p/12753019.html
Copyright © 2011-2022 走看看