目录:

一:学习内容
贪心算法
外加补充stl内容:
1.queue
2.stack
二:用所学解决的问题
三:本周感想

学习内容:

queue:

头文件:#include< queue>
基本操作:
queue< int >q;
q.back()返回最后一个元素;
q.empty()如果队列为空则返回真;
q.front();返回第一个元素;
q.pop()删除第一个元素;
q.push()在末尾加入一个元素;
q.size()返回队列中元素的个数;
队列符合先进先出后进后出的规则;
内部默认数据存放容器为deque,若要用非默认容器初始化,必须要在模板中指定容器类型。

stack:

头文件:#include< stack >
基本用法:
stack< int>p;
p.empty()栈为空则返回真;
p.pop()移除栈顶元素;
p.push()在栈顶添加元素;
p.size()返回栈中元素数目;
p.top()返回栈顶元素;
stack的实现很简单,只需要将底层结构进行约束就可以了。
由于stack后进先出的规则,所以并无走访功能,且stack是没有迭代器的。

:贪心算法:

前面所整理的都是贪心算法所涉及到的所需要的具体工具;因为贪心算法就基本讲完了,这里就总结总结自己所消化的贪心算法。
个人感觉,贪心算法顾名思义,就是一种鼠目寸光只考虑当前最优,不考虑影响之后的算法,没什么固定的套路,就是要最优就完了。思维很重要,有的题你就是会考虑一天没啥感觉,一看题解恍然大悟,整的我很烦躁,当然也有基本的思路啦,比如把问题分解来看,寻找局部的最优解,然后结合成原来问题的最优解,但是据我搜索得来,贪心并不一定能得到某些问题的最优解,但也是最优解的近似。
(个人之见,思路有些乱,这大晚上的想到啥就写些啥呗)
在这写写做题心得叭:有些题一定要在纸上写写画画,刚才整理的一道贪心题就是画了半天才搞懂的(具体请看训练总结篇 第四周周结);再有就是,某个思路写的代码改了好几遍不通过就更该个思路,话不多说了整两个真题。

用所学解决的问题:

:最小新整数

描述
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。
现在从m位中删除k位(0<k < m),求生成的新整数最小为多少?
例如: n = 9128456, k = 2, 则生成的新整数最小为12456

输入
第一行t, 表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
样例输入
2
9128456 2
1444 3
样例输出
12456
1

题目理解:就是很简单的删数问题,删掉原来k个数,在不改变顺序的情况下使得剩下的数最小。
一开始的思路就是从下标为0开始遍历,如果x[i]>x[i+1]就删掉第i个数知道删完k个为止,输出的时候再保证前面的0去掉就OK了感觉也蛮简单的,也就是以下这个代码

#include<iostream>
#include<cstring>
using namespace std;
int main()
{char m[100];int t,k;cin>>t;while(t--){cin>>m>>k;int len=strlen(m);for(int i=0; i<k; i++){for(int j=0; j<len-1; j++){if(m[j]>m[j+1]){for(int r=j; r<len-1; r++)m[r]=m[r+1];break;}}len--;}int i=0;while(m[i]!=0)i++;for(int j=i; j<len; j++)cout<<m[j];cout<<endl;}return 0;
}

但是没有通过,于是改了好久好久,感觉没啥错但就是不通过,个人认为应该就是多重for循环,复杂度高,所以后来写了while语句也就是下面的代码

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{int t, k, m;char str[20];cin >> t;while(t--){cin >> str >> k;m = strlen(str);while(k--){for(int i = 0; i < m; i++)if(str[i] > str[i+1]){for(int j = i; j<m; j++)str[j]=str[j+1];break;}m--;}cout<<str<<endl;}return 0;
}

虽然通过了但觉得不是很严谨,然后看了课件,尝试了另一种思路,就是从n个数中删掉k个换一种思维改成选择n-k个;因为要删掉k个数所以每次选择的数就是从第i个到k+1个数中选一个,下一次选择的数一定在这个数的后面所以下一次选就在本次x[i+1]到x[k+2]因为已经选过一个了所以还要再选n-k-1个所以就是到k+2之后依次类推,而且确实要除去前导0的,大概是测试数据的问题所以我那个题通过了。

Pearl Pairing

描述
At Bessie’s recent birthday party, she received N (2 <= N <= 100,000; N%2 == 0) pearls, each painted one of C different colors (1 <= C <= N).

Upon observing that the number of pearls N is always even, her creative juices flowed and she decided to pair the pearls so that each pair of pearls has two different colors.

Knowing that such a set of pairings is always possible for the supplied testcases, help Bessie perform such a pairing. If there are multiple ways of creating a pairing, any solution suffices.
输入

  • Line 1: Two space-separated integers: N and C

  • Lines 2…C + 1: Line i+1 tells the count of pearls with color i: C_i
    输出

  • Lines 1…N/2: Line i contains two integers a_i and b_i indicating that Bessie can pair two pearls with respective colors a_i and b_i.
    样例输入
    8 3
    2
    2
    4
    样例输出
    1 3
    1 3
    2 3
    3 2

题目大意:有n个珍珠,每个珍珠涂上c钟不同颜色中的一种。
让你给珍珠配对让每对珍珠有两种不同的颜色;随意输出一种配对方式即可;
题目解析:
我想的就很简单就是记录每种颜色的珍珠有几个并记录他是第几种(也就是下标),然后从小到大按照颜色顺序大小排序(因为是随意的答案,一种感觉就觉得这样挺对,所以就这样写了),排序之后分为两组前n/2和后n/2。具体实现就是下面的代码了。但是是错误的。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int n,c,a[100005],b[100005],l=1;
struct cc1
{int c1;int c2;bool operator<(const cc1 b){return c1>b.c1;}
}cc[100005];
int main()
{cin>>n>>c;for(int i=1; i<=c; i++){cin>>cc[i].c1;cc[i].c2=i;}sort(cc+1,cc+c+1);for(int i=1;i<=n/2;i++){cc[l].c1--;a[i]=cc[l].c2;if(cc[i].c1==0)l++;}for(int i=1; i<=n/2; i++){   cc[l].c1--;cout<<a[i]<<" "<<cc[l].c2<<endl;if(cc[l].c1==0)l++;}
}

因为这个代码错误试,改了很多次也不太对,所以大概是思路错了,所以又在纸上写了样例去尝试别的思路,然后发现因为数据保证存在答案,所以n一定会是偶数,并且每种颜色的珍珠也不可能超过n/2个,所以只需要枚举n/2个就可以了,其实也还是分为两组每次取两组的第i位,(有点我原来的思路优化一下的意思)至于要不要sort排序,好像这道题没必要因为存数组的时候就是按照从小到大存的。具体实现就是以下代码了。

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n,c,s[100005],a,r;
int main()
{cin>>n>>c;for(int i=1;i<=c;i++){cin>>a;for(int j=1;j<=a;j++){s[r]=i;r++;}}for(int i=0;i<n/2;i++)cout<<s[i]<<" "<<s[i+n/2]<<endl;return 0;
}
拼点游戏

描述
C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力,小者获得一颗巧克力,如果点数相同,每人各得二颗巧克力,使用过的卡牌不得重复使用。已知C和S取到的卡牌点数,请编程计算S最多和最少能得到多少颗巧克力。
输入
输入包含多组测试数据。
每组测试数据的第一行是一个整数n(1<=n<=1000),接下来一行是n个整数,表示C抽到的白色卡牌的点数,下一行也是n个整数,表示S抽到的蓝色卡牌的点数。
输入的最后以一个0表示结束。
输出
对每组数据,输出一行,内容是两个整数用空格格开,分别表示S最多和最少可获得的巧克力数。
样例输入
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
样例输出
9 5
4 4
4 4

题目解析:
题意很简单,就是谁大加三分谁小加一分一样大都加两分,求分数的最大值和最小值;
我的思路呢最大值就是两个数组都sort从小到大排序,然后用s里面的数去依次和c的数去比,只要有比c得数大的就结果就加三如果没有就比是否有等于的就加二再就是小于了只能加一, 每次要有一个判断条件,看是否需要再比较等于或者小于。最小值呢就是两个数组反过来就好了。具体实现就是以下代码。但是是错误的。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{int n,i,c[1001],s[1001],cc[1001],ss[1001];while(cin>>n){memset(c,0,sizeof(c));memset(cc,0,sizeof(cc));memset(ss,0,sizeof(ss));memset(s,0,sizeof(s));if(n==0)break;for(i=0; i<n; i++){cin>>c[i];cc[i]=c[i];}for(i=0; i<n; i++){cin>>s[i];ss[i]=s[i];}sort(c,c+n);sort(s,s+n);sort(cc,cc+n);sort(ss,ss+n);int maxx=0,m=n;for(int i=0; i<n; i++){int pp=0;for(int j=0; j<m; j++)if(s[j]>c[i]){maxx+=3;for(int k=j; k<m-1; k++)s[k]=s[k+1];m--;pp=1;break;}if(pp==1)continue;for(int j=0; j<m; j++)if(s[j]==c[i]){maxx+=2;for(int k=j; k<m-1; k++)s[k]=s[k+1];m--;pp=1;break;}if(pp==1)continue;for(int i=0; i<m-1; i++)s[i]=s[i+1];m--;maxx+=1;}int minn=0,mm=n;for(int i=0; i<n; i++){int pp=0;for(int j=0; j<mm; j++)if(cc[j]>ss[i]){minn+=3;for(int k=j; k<mm-1; k++)cc[k]=cc[k+1];mm--;pp=1;break;}if(pp==1)continue;for(int j=0; j<mm; j++)if(cc[j]==ss[i]){minn+=2;for(int k=j; k<mm-1; k++)cc[k]=cc[k+1];mm--;pp=1;break;}if(pp==1)continue;for(int i=0; i<mm-1; i++)cc[i]=cc[i+1];mm--;minn+=1;}minn=4*n-minn;cout<<maxx<<" "<<minn<<endl;}

提交不对……哎,所以继续老办法找别的思路呗。
当我再读这个题的时候想到了高中课文田忌赛马的游戏,感觉就是同样的游戏啊。但是知道有啥用还是觉得我那个思路挺对的,但却是不行,不能固化思维,所以就在纸上验算样例,然后就发现原来方法比较麻烦不用盲目的挨个比较,只要s的最大的和c的最大的比 如果大就加3并移动下标到两个的次大的,否则就比较最小的,如果s大就加3并移动下标到次小,否则就比较s小和c大如果能相等加个2就加2不能就只能加一了,然后s小到次小c大到次大。也就是记录下标,让下标去移动。因为每次比较都一共有四块巧克力,所以s的最小就是4*n-c的最大,具体实现就是下面的代码。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int solve(int c[1005],int s[1005])
{int ans=0;int cl=1,cr=n,sl=1,sr=n;while(sl<=sr){if(s[sr]>c[cr]){--sr;--cr;ans+=3;}else if(s[sr]<c[cr]){++sl;--cr;ans+=1;}else{if(s[sl]>c[cl]){++sl;++cl;ans+=3;}else{if(s[sl]<c[cr]){++sl;--cr;ans+=1;}else{++sl;--cr;ans+=2;}}}}return ans;
}
int main()
{while(cin>>n,n){int a[1005];int b[1005];for(int i=1; i<=n; ++i)cin>>a[i];for(int i=1; i<=n; ++i)cin>>b[i];sort(a+1,a+1+n);sort(b+1,b+1+n);cout<<solve(a,b)<<" "<<4*n-solve(b,a)<<endl;}
}

本周感想:

贪心没啥固定套路所以思维显得尤为重要,但是题做多了那种思维也会一看题就会想出来,就算不对也就是优化优化就可以了,所以做题真的很重要。还有就是一定不能想到一种思路就局限在这种思路里面,提交不对那就跳出去,去重新读题换个角度去思考,可以尝试把问题转变成别的问法,然后自己去求解,蛮实用的。继续加油吧~~

We must accept finite disappointment, but we must never lose infinite hope.

(sdau) Summary of the third week.相关推荐

  1. (sdau) Summary of the fourth week.

    目录: 一:学习内容: 动态规划/线性DP 二:用所学解决的问题 三:本周感想 学习内容: 简单概述: 线性动态规划,是较常见的一类动态规划问题,就是在线性结构(堆栈)上进行状态转移,这类问题没有固定 ...

  2. .net面试问题汇总(转)

    用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 答: 从下至上分别为:数据访问层.业务逻辑层(又或成为领域层).表示层 数据访问层:有时候也称为是持久层,其 ...

  3. .net 中struct(结构)和class(类)的区别

    1.struct 结构与class(类)的区别 1)struct是值类型,class是对象类型 2)struct不能被继承,class可以被继承 3)struct默认访问权限是public,而clas ...

  4. C# 视频监控系列(7):服务器端——封装API(下)(1)

    前言 写系列文章的时候[前言]部分变得无言了,可能来得顺利了点吧: ) 本章中提供的封装均是我用笨办法从<<Hikvision 板卡网络开发包编程手册V4.7>>和<&l ...

  5. BlogEngine(4)---Widget小部件

    前面的两篇文章中,我们分别介绍了BE的插件和主题机制,这一篇我们来看看BE三大特性中的最后一个:Widget. 所谓的widget,在BE中可以理解为一块特定的显示区域,在这个区域中可以用来显示文章分 ...

  6. 访问者(Visitor)模式

    访问者(Visitor)模式:访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. /* * 抽象访问者(Visitor)角色: ...

  7. Entity Framework 实体框架的形成之旅--为基础类库接口增加单元测试,对基类接口进行正确性校验(10)...

    本篇介绍Entity Framework 实体框架的文章已经到了第十篇了,对实体框架的各个分层以及基类的封装管理,已经臻于完善,为了方便对基类接口的正确性校验,以及方便对以后完善或扩展接口进行回归测试 ...

  8. 厚积薄发,丰富的公用类库积累,助你高效进行系统开发(11)---各种线程相关操作类...

    俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力. 本篇的公用类库的介绍主题是程序开发中多线程操作环境中,常用到的线程相关类,本篇 ...

  9. ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await

    PS:异步编程的本质就是新开任务线程来处理. 约定:异步的方法名均以Async结尾. 实际上呢,异步编程就是通过Task.Run()来实现的. 了解线程的人都知道,新开一个线程来处理事务这个很常见,但 ...

最新文章

  1. onmouseout事件与onchange事件分析
  2. 一份传世典文:十年编程(Teach Yourself Programming in Ten Years)
  3. 【重温经典】张小龙:微信背后的产品观
  4. Dijkstrala算法
  5. win7分区c盘调整容量_C盘空间不足变红咋办?清理垃圾瘦身不如扩容,硬盘容量调整教程...
  6. linux 1t 分区,Linux磁盘管理——swap分区
  7. SQL笔记(1)索引/触发器
  8. 有长度要求的区间最大值
  9. C# 反射/映射学习
  10. rem和mod的区别
  11. 路由器当ap用虚拟服务器不能用,解决用TPLINK路由器配置模拟AP时Internet连接共享是空白的问题...
  12. 【自学与引导】 大数据技术 技能课程总结篇
  13. 常来长安——西安游记(我愿称之为博物馆七日游)
  14. 同相加法器电路图_反相加法器电路图_运放加法器电路图解析
  15. uni.navigateTo失效
  16. Python每日一练-----快乐数
  17. android 系统的切图方式_UI设计规范一Android尺寸单位换算及切图规范
  18. 【数据结构】循环队列的front,rear指针以及队列满的条件、计算队列长度
  19. 方法被重写时的调用问题
  20. 软件测试工作的感想怎么写,软件测试工作中的一些感悟

热门文章

  1. 基于消息中间件解决分布式事务的开源框架Myth
  2. 为什么一定要从DevOps走向BizDevOps?
  3. 有道云笔记突然出现乱码 日记变成乱码
  4. 机器学习在癌症数据集上的应用实践
  5. FITC标记,CY5标记,CY3标记,CY5标记,CY5.5标记,CY7标记,CY7.5标记金纳米团簇
  6. 计算机算法设计与分析(第5版)PDF
  7. 能用10年的电动车牌子是什么?绿源电动车了解一下吧
  8. Tetramax生成SPF文件的方法
  9. 【统计学】推断统计分析——根据样本统计量推断总体参数
  10. 时序预测 | MATLAB实现GWO-LSTM灰狼算法优化长短期记忆神经网络时间序列预测