ACM Day6

位运算符:
&:
9&5=1
1001
&0101
------
0001
&运算符即为只有全部为1的话才是1 其他情况均输出0

|:
9|5=13
1001

0101

1101
|位运算符即为有1的话就均为1只有两个0的情况才为0

^:
9^5=12
1001
^0101
------
1100
^位运算符即上下相同为1不同为0

~:
~9=65526
~0000000000001001=1111111111110110
~位运算符即为求出相对应的反码

<<:
9<<2=36
1001<<2=100100
<<即为左移几位,最后的值取决于进制和左移的数目,比如二进制左移一位总的值乘2

:
9>>2=2
1001>>2=2

位运算符即为右移,最后的值取决于进制的右移的数目,比如二进制右移一位总的值除以2

判断一个数的奇偶:
奇数:
x&1=1
****************1
&00000000000000001
------------------------
00000000000000001
奇数在最后均为1

偶数:
y&1=0
****************0
&00000000000000001
------------------------
00000000000000000

偶数在最后均为0

STL优先队列:
priority_queue

empty()    如果队列为空,则返回真

pop()    删除对顶元素,删除第一个元素

push()    加入一个元素

size()     返回优先队列中拥有的元素个数

top()     返回优先队列对顶元素,返回优先队列中有最高优先级的元素

1、普通方法:

priority_queue q;              //通过操作,按照元素从大到小的顺序出队
priority_queue<int,vector, greater > q;   //通过操作,按照元素从小到大的顺序出队
2、自定义优先级:

struct cmp {
  operator bool ()(int x, int y)
  {
     return x > y;   // x小的优先级高 //也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
  }
};
priority_queue<int, vector, cmp> q; //定义方法
//其中,第二个参数为容器类型。第三个参数为比较函数。
3、结构体声明方式:

struct node {
  int x, y;
  friend bool operator < (node a, node b)
  {
    return a.x > b.x; //结构体中,x小的优先级高
  }
};
priority_queueq; //定义方法
//在该结构中,y为值, x为优先级。
//通过自定义operator<操作符来比较元素中的优先级。
//在重载”<”时,最好不要重载”>”,可能会发生编译错误
优先队列可以在每次压入一个数据的同时进行自动排序,可减少调用函数的时间,效率更快

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。

每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 n-1n−1 次合并之后, 就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为 11 ,并且已知果子的种类 数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

#include<bits/stdc++.h>
using namespace std;

int main()
{
	priority_queue<int, vector<int>, greater<int> >q;
	int n;
	cin >> n;
	int x;
	while (n)
	{
		cin >> x;
		q.push(x);
		n--;
	}
	int ans = 0;
	while (q.size() >= 2)
	{
		int a = q.top();
		q.pop();
		int b = q.top();
		q.pop();
		ans += (a + b);//每次均取最小的两个数相加
		q.push(a+b);//吧每次移动的总数量叠加
	}
	cout << ans << endl;
	return 0;
}

记忆化搜索:
在开头用一个大小合适的数组并把它初始化为0或者其他适合的条件
在调用函数中给它赋值,用数组存取所有已经算过的数据的值,一旦需要用到之前已经存过的数据就直接返回不需要在继续往下算,可节省很多时间,比如初始化为0的情况 在每次给数组赋值的情况下 判断if(a[i]) return a[i] 即可节省下递归的操作

利用位运算求取x^y:

int ksm(int x,int y){//求模运算,这里是快速求模运算。 
                            //VS 2017虽然把__int64作为了一种内置类型,但是也做了类似的处理,使得__int64与long long没有肉眼可见的差别。
        int ans1=1;
	    while (y){
        if (y&1) //逐位与运算,通过和1相与,保留最后一位 
		  ans1=1ll*ans1*x%Mod;//通过乘以1ll,将等号右边的精度提高到long long ,低精度向高精度转化,避免中间结果溢出范围,右边的ans现在是64位的int
		                     //原来32位的int型 10位数字,long long 19位数字, 1e+9是9位数字, 所以是32位还是64位都不会超出范围。 
          y>>=1;//右移相当除以2,类比十进数,右移一位相当于除以10,同理左移,是乘以相应的进制基数。 
		  x=1ll*x*x%Mod;//x中记录每次翻倍的求模的结果。 
        }
	   return ans1;
}

在数字大的情况下一个需要进行n次循环 一个需要logn次循环,数字越大位运算求取x^y需要的时间越少,节省的时间越多,相比之下优越性越大

C++STL自定义排序:(大部分适用于结构体)
在头文件#include下有一个sort排序即为快速排序
可加入一个自定义函数 bool cmp()可在里面自定义优先级排序和排序规则
在进行排序的时候只需要调用sort(a,a+n,cmp)即可

某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:

院士奖学金,每人80008000元,期末平均成绩高于8080分(>80>80),并且在本学期内发表11篇或11篇以上论文的学生均可获得;
五四奖学金,每人40004000元,期末平均成绩高于8585分(>85>85),并且班级评议成绩高于8080分(>80>80)的学生均可获得;
成绩优秀奖,每人20002000元,期末平均成绩高于9090分(>90>90)的学生均可获得;
西部奖学金,每人10001000元,期末平均成绩高于8585分(>85>85)的西部省份学生均可获得;
班级贡献奖,每人850850元,班级评议成绩高于8080分(>80>80)的学生干部均可获得;
只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是8787分,班级评议成绩8282分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是48504850元。

现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)

#include<iostream>
#include<algorithm>
using namespace std;


struct student
{
	char name[25];
	int Class;
	int test;
	char leder;
	char isEast;
	int num;
	int money=0;
	int number;
}a[105];

bool cmp(student x, student y)
{
	if (x.money != y.money) return x.money > y.money;
	else return x.number < y.number;

}
int main()
{
	int N;
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> a[i].name >> a[i].test >> a[i].Class >> a[i].leder >> a[i].isEast >> a[i].num;
		a[i].number = i + 1;
	}
	int sum = 0;
	for (int i = 0; i < N; i++)
	{
		if (a[i].test > 80 )
		{
			if (a[i].num >= 1)//院士
				a[i].money += 8000;
			if (a[i].test > 85 && a[i].Class > 80)//五四
				a[i].money += 4000;
			if (a[i].test > 85 && a[i].isEast == 'Y')//西部
				a[i].money += 1000;
			if (a[i].test > 90)//成绩优秀
				a[i].money += 2000;
		}
		if (a[i].leder == 'Y'&&a[i].Class>80)//干部
			a[i].money += 850;
		sum += a[i].money;
	}
	sort(a, a + N, cmp);
	cout << a[0].name << endl;
	cout << a[0].money << endl;
	cout << sum << endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值