【蓝桥每日一题]-贪心(保姆级教程 篇2)#纪念品分组 #gcd排序

目录

题目:纪念品分组

思路:

题目:gcd排序

思路:

题目:纪念品分组

      

【蓝桥每日一题]-贪心(保姆级教程 篇2)#纪念品分组 #gcd排序_第1张图片【蓝桥每日一题]-贪心(保姆级教程 篇2)#纪念品分组 #gcd排序_第2张图片

          

思路:

贪心思路:先将数据从小到大排序(默认),然后让最左边l和最右边r匹配,如果可以就分成一组,如果不行就让r单独一组。

      
(因为目前最小的都不能和r一组了,所以要放弃r的分组)l继续匹配下一个。直到把所有数据完全分组即可。
  

#include                    
using namespace std;
int W,ans=0;
int n,a[30001];
int l,r,i;
int main()
{
    cin>>W>>n;
    for(i=1;i<=n;i++)
      cin>>a[i];
    sort(a+1,a+n+1);
    l=1;  r=n;
    while(l<=r)//一定要有等号,因为如果没等号的话,可能导致最中间的数据无法遍历分组
    {
        if(a[l]+a[r]<=W)   //如果能分就分到一组
          l++,r--,ans++;
        else
          r--,ans++;   //不能就让r单独一组
    }
    printf("%d",ans);
    return 0;
}

   

   

   

题目:gcd排序

 (来自codeforces(893)的一题)题意:将数组1~n进行排列,得到每组的gcd(a[i],a[i+1]),其中不同的数越多,分数越高,问最大分的排列方式

比如输入5:我们应该排列成1 2 4 3 5 然后获得gcd数(1 2 1 1 1)得到分数为2,因为有两个不同的gcd数嘛。无论你再怎么排列也找不到得分更高的了。

        

思路:

cf里面的题比较考思维,主要是枚举简单数据寻找规律就行,我们发现后一个数是前面的倍数时就可以把前面的数取做新的gcd数,所以就按这样排列。

       

啊,听不懂?那举个例子,输入10 开始

   

我们先排列从1开始安排:1 2此时获得gcd(1),那么紧接着安排上4,变成1 2 4就获得了gcd(1 2),然后安排上8,变成gcd(1 2 4),然后没有16,那么8是不可能成为gcd的

    

然后从3开始安排 :3 6 (12没有不管了)

    

然后从5开始安排:5 10

     

然后从7开始安排:7

    

然后从9开始安排:9

    

最后获得排列顺序1 2 4 8 3 6 5 10 7 9,这样就能获得最多的不同的gcd个数

    

       

#include  
using namespace std;
const int N=1e5;
int a[N];
int main(){
	int t;cin>>t;
	while(t--){
		int n,cur=0;cin>>n;
		for(int i=1;i<=n;i+=2)//1,3,5,7,9,开始往后翻倍
		  for(int j=i;j<=n;j*=2){//虽然我证明不出来,但是确实所有例子都符合呀
		  	 a[++cur]=j;
		  }
		for(int i=1;i<=n;i++){
			cout<

你可能感兴趣的:(算法,数据结构,c++,贪心,贪心算法)