自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(45)
  • 收藏
  • 关注

原创 合并排序-MergeSort

两个排好序的数组合并都很简单,但到具体怎么二分递归及代码实现就脑子短路了比如递归返回什么?递归到最后怎么排序?我还以为是每次递归回来就合并再返回到上一层,返回后用啥装呢?……我还以为每次把传过来的数组分成两个数组再进行操作……也不是说完全想的没道理,就是想的太乱了。首先,总共需要两个void函数,两个数组。两个函数分别用来递归和每层递归后的最后的合并;而一切的操作并不是通过每层创建两个临时数组实现,而是直接在A数组本身上操作,B数组起辅助作用...

2022-06-15 22:09:07 346 1

原创 洛谷P1443 马的遍历

不能用dfs!int num[405][405],mem[405][405]={0};//int d[8][2]={2,1,1,2,-1,2,-2,1,2,-1,1,-2,-1,-2,-2,-1};int dx[8]={2,1,-2,-1,2,1,-2,-1},dy[8]={1,2,-1,-2,-1,-2,1,2};int n,m,x,y;void dfs(int a,int b,int k) { for(int i=0;i<8;i++) { int p=a+dx[i

2022-05-06 14:38:08 266

原创 洛谷P2392 kkksc03考前临时抱佛脚

为啥贪心不行!每次哪边用时少就把当前最大值放进去,竟然0分仔细想想很容易找出反例最完美的情况肯定是左右脑所用时间相同,各t(总)/2的时间以此可找出反例:5 4 3 3 3用01背包解决,找到最接近t/2的情况int main() { int s[4],sum=0,t[30],p; for(int i=0;i<4;i++) cin>>s[i]; for(int i=0;i<4;i++) { p=0; for(int j

2022-05-04 23:58:48 300

原创 洛谷P2678 [NOIP2015 提高组] 跳石头

每次都要比较哪两块石头间距最小,同时比较隔壁的间隙,相加最小的那块石头剔除,而且删除后还要将数组后面的往前移,再重新比较间隙最小的在哪里,而且如果是第一个块石头,需要特判……综上,不会写看题解直接从答案出发,好家伙!有的时候,我们会遇到一些特殊的问题:它们很难直接求解,或者根本无法直接求解,这种时候就应该换个角度,从答案方面入手。第一个题解写的也特别好,加深了我对二分的理解:最优解一定可行,但可行解不一定最优。我们假设整个序列具有单调性,且一个数x为可行解,那么一般的,所有的x’(x’<x

2022-04-21 16:14:45 167

原创 洛谷P2440 木材加工

int main() { int n,k,L[100005],sum; int l=0,m,r=0; cin>>n>>k; for(int i=0;i<n;i++) {cin>>L[i];r=max(r,L[i]);} while(l<r) { m=(l+r+1)/2;//为了能让l最后等于r sum=0;//别忘了重制! for(int i=0;i<n;.

2022-03-31 12:07:03 165

原创 洛谷P1678 烦恼的高考志愿

题解没看懂为啥它找下限还会有b-a[r-1]又做了一题二分,加深了理解int main() { int m,n; int a[100005],b; int sum=0;//用double就会有一个点wr?why cin>>m>>n; for(int i=0;i<m;i++) cin>>a[i]; sort(a,a+m);//注意是m! for(int i=0;i<n;i++) {

2022-03-29 22:53:49 234

原创 洛谷P1024 [NOIP2001 提高组] 一元三次方程求解

最近失恋了(其实只是被单方面丑拒罢了),二分查找感觉有多种情况,左右端点是否是开区间,特判之后,有要求第一个出现的位置;有普通的二分查找到那个整数;有查找到需要的精度……double a,b,c,d;double x1,x2;double l,mid,r;double f(double x) { return a*x*x*x+b*x*x+c*x+d;}int main() { cin>>a>>b>>c>>d; f

2022-03-29 20:32:48 143

原创 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树

很简单的一题,但是二分我还是有很多困惑,具体表现为除去标准的二分,我自己写的二分为啥老是有问题int main() { int n,m,h[1000004]; ll sum; int l=0,mid,r; cin>>n>>m; for(int i=0;i<n;i++) { cin>>h[i]; r=max(r,h[i]); } while(l<=r){ sum=0;

2022-03-26 10:39:17 182

原创 洛谷P1102 A-B 数对

不用说都知道o(n*n)会超时,遍历数组,找到对应A的A+C(B)个数两种方法:二分查找VSmaplower_bound(a,a+n,x)-a //下标从0开始lower_bound(a+1,a+n+1,x)-a //下标从1开始upper_bound(a,a+n,x)-a //下标从0开始upper_bound(a+1,a+n+1,x)-a //下标从1开始//返回所要找的数的后一个(比他大)的位置int main() { int n; ll f[

2022-03-24 20:14:25 150

原创 洛谷P2249 【深基13.例1】查找

虽然就是普通的二分而已,但对我这种“高手”来说,没有什么是我会的(骄傲.jpg)1.循环结束条件是什么,左端点=右端点还是找到那个数了2.非降序的序列怎么保证找到的那个数第一次出现的位置3.如果就在端点处,怎么让“mid”移动到端点处int n,m,f[1000005],q,pos;int find(int q) { int l=0,r=n-1; while(l<r) {//循环直到左端点等于右端点 int mid=(l+r)/2;//计算中点坐标

2022-03-24 10:23:35 343

原创 洛谷P1080 [NOIP2012 提高组] 国王游戏

这是我的第一版,超级简单,但有个点ac不掉,想了半天才发现我理解错那个规律了struct people{ int a,b; bool operator <(const people x) const{ return a*b<x.a*x.b; }}p[1005];int main() { int n; cin>>n; for(int i=0;i<=n;i++) cin>>p[i].a>&gt

2022-03-22 23:50:19 3539

原创 洛谷P4447 [AHOI2018初中组]分组

终于不是水题了,第一版想的太简单了,很多情况没考虑到,关键就是当遇到重复的部分时该怎么分组//第一次尝试-失败:遇到重复就断掉重开一个组,显然只满足部分情况int main() { int n; cin>>n; ll a[n+10]; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); int min=100000,p=1; for(int i=1;i<n;i++) {

2022-03-21 10:54:57 515

原创 洛谷P4995 跳跳

这两天的题目太水了,存个档int main() { int n,h[305]={0}; ll s=0; cin>>n; for(int i=1;i<=n;i++) cin>>h[i]; sort(h,h+n+1); /*bool flag=1; for(int i=0,p=0;i<n;i++) { if(flag) {s+=pow((h[p]-h[p+n-i]),2);p+=n-i;flag=0;}

2022-03-20 00:58:53 60

原创 洛谷P5019 [NOIP2018 提高组] 铺设道路

应该不可以将d[i]直接排序吧,会破坏原有的顺序关系题目描述的有瑕疵啊,“首位相连”但后面的“连续区间”又是只能单一从前往后铺路不管是贪心还是递推原理都一样:以第一块开始,如果下一块深度没有前一块深,就相当于“免费”顺便铺的,但一旦到某块比前一块深,之前的“免费链”就断了,但“白嫖”过之前的a[i-1]块砖,所以只需要再铺a[i]-a[i-1]块就够了;当遍历到最浅的那个坑时,下一个肯定会断,不过总体的深度都一起减少了之后的每块深度都用一样的规律分析。理解还是很抽象,和上一题一样规律都贼简单,但

2022-03-17 01:30:43 454

原创 洛谷P1106 删数问题

不会写!不会写!不会写!第一行输入到数组我能想到的只是先有string存储,再一个个放到数组里最后肯定是剩下len-k位,但不是单纯的找最小的len-k个,比如:4 3 1 2 5这种情况还和1在序列中的位置有关看了好多题解最好理解的就是:删除靠前的“山峰”虽然规律很简单,但要真正理解又很抽象循环k次,每次从0到len-1遍历,删除第一个比后面大的数字,删除便跳出接下来的遍历,因为一次只能删一个,否则之前已经遍历过的就会成为漏网之鱼。如果这次遍历有找到“山峰”,删除后len-1;但是如果已经全

2022-03-15 01:26:53 360

原创 洛谷P3817 小A的糖果

感觉情况很多呀,以x/2为分界线,不能有超过两个盒子里的糖果超过他。如果一个盒子里的糖果大于x/2且为t,那么剩下的所有的糖果都不能超过x-t。而且要求的是最少的那种情况,那到底是把糖果多的盒子全吃到x/2还是把小于x/2的全吃到x-t。这还取决于有多少糖果多的盒子和多少糖果少的盒子。!!!干脆把眼睛珠子挖出来算了,“每相邻两个盒子”所以每两个两个比较,如果两个相加s大于x,则总共要吃掉s-x个糖果,而为了贪心让总吃的最少,所以每次吃第二个盒子里的糖果肯定最赚,因为这样下次再两两比较吃的也肯定最少.

2022-03-14 00:03:27 150

原创 洛谷P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

果不其然,我是个sb,想着:嘿,这题怎么这么简单。然后提交只有十分,我还不是那种因为超时而没分,他们至少还读懂了题,我竟然连每次合并完都得重新排序都没想到,因为每次需要的是目前最小的两个呀。竟然有一种东西叫做优先队列,完全契合这题啊。用法详情可以参考这篇文章clicktop 访问队头元素push 插入元素到队尾 (并排序)pop 弹出队头元素//升序队列priority_queue <int,vector<int>,greater<int> > q;但不

2022-03-13 00:36:29 1497

原创 洛谷P1803 凌乱的yyy / 线段覆盖

非常典型的贪心算法问题,但并不妨碍我不会写去看题解想要贪心其实就是每次都选结束时间最早的那个,当然前提是它的开始时间不冲突虽然规律很简单,但其实真的不太好理解(对我)。每次选结束最早的那个反正至少不会亏,每次都不亏,最后就是最赚的。比如说我选结束最早的那个,不可能说同时有两个比赛错过了。struct game{ int a,b;};bool cmp(game x,game y) { return x.b<y.b;}int main() { int n,s=0,

2022-03-11 17:08:10 965

原创 洛谷P1223 排队接水

经过昨天那道题,今天这道就很简单了,就算不知道哪种顺序最佳,看给出的实例就能看从小到大排序,而且最后计算平均等待时间的时候也就明白为啥这样排最省时了。看题解提供一种思路:换一种存数据的方式struct wt{ int o; int t;}a[1001];bool cmp(wt x,wt y) { return x.t<y.t;}int main() { int n; double s=0; cin>>n; for (int

2022-03-10 10:50:25 104

原创 洛谷P2240 【深基12.例1】部分背包问题

又是不会写的一天,想法很简单,就是将重量价值比从大到小排序一下,但是怎么连带着m,v一起排呢太没用了,又去看了题解,竟然直接用一个struct,更改一下sort的cmp,用sort或者不用struct,冒泡排序,三个数组一起排序。struct coin{ double w;//后面相除得考虑精度问题,所以不用int,不然得*1.0,强制转换 double p;}a[101];bool cmp(coin x,coin y) { return x.p*y.w>y.p*x

2022-03-09 19:11:34 357

原创 洛谷P1498 南蛮图腾

该怎么输出,第一行随着输入的不同起始位置也在改变,可以将空白的部分也看成和三角类似的字符串吗,毕竟他们的面积有倍数关系;哦,不能直接cout单独一个三角,因为随着输入不同,每行也都不相同,所以应该用二维数组没想道遇到的最大的问题是转义序列"/__\“这样就会报错,解决办法就是改成”/__\\"而这题我的第一想法是一边计算一边输出,看了题解的分治方法是先存储在一个很大的数组里,经计算修改数组里的值,最后“倒序”输出。这题要想直接模拟很难,因为会找错规律,图腾是“复制”过来的而不管是杨辉三角还是分治的思

2022-03-08 21:49:18 1195

原创 洛谷P1010 [NOIP1998 普及组] 幂次方

第一个想法:要用字符串输出吗思维太死板了,为什么一定要先全部存储再输出第一稿写的乱七八糟,一是没真正理解这个题目,第二个是对与递归还没有真正懂,纠结’(’ ‘0’ ')‘这些符号递归时放哪里,但其实更应该把每个从’(‘到’)'的部分看成一个整体总之:转化为2进制+递归经修改后的代码很漂亮!void dfs(int n) { int k=1,count=0; while(k*2<=n) { k<<=1; count++; }

2022-03-08 00:19:42 138

原创 洛谷P1259 黑白棋子的移动

这道题感觉是最简单的了,就直接模拟就行了,最后四、五行特殊输出。但这样就感觉没啥意思了,学不到什么。唯一值得注意也许是很多重复的操作可以封装起来。看了题解后,也可以用分治的思想,更多的是加强思维。//封装前char s[205];int n;void print() { for(int i=1;i<=2*n+2;i++) cout<<s[i];//putchar(s[i]); cout<<endl;//putchar('\n');}int ma

2022-03-07 00:50:36 176

原创 洛谷P1228 地毯填补问题

我也是服了,这道题加上我拖延,竟然整整写了一天!不过幸好还是写出来了,这题也不太好理解用分治的思想,真就把一个复杂的问题,一步一步拆成了小问题解决了!首先,如果是2x2的格子最简单,不管在哪里,都有一种地毯填补;不管是4x4还是8x8,都能拆分成很多个2x2。所以我们要做的就是先判断(x,y)在哪里方向,(比起判断0<x<len,好像的确用x-a,y-b更简便些)确定之后就能确定一个地毯,将这个地毯的三块分别看作公主站位,递归解决对应方向的所有格子上图:输出的坐标,x,y,a,b转

2022-03-06 01:00:35 348

原创 洛谷P3612 [USACO17JAN]Secret Cow Code S

用递归直到字符串长度足够,那怎么将字符串逆反再加进原字符串后面,不会用char数组遍历吧……天啊,以上是我初步的想法,太蠢了,首先这题不能模拟,因为N≤10^18,而且就算要模拟,只要用循环就够了,最后题目都没看清,不是逆反!所以这道题还是得递推找规律,除了第一个是由上一次最后一个旋转过来的,其他的都往左平移就行了,(那按照这种思想,就算是逆反,也能找到坐标之间的关系。)上图:所以思路就是从n开始,将字符串右边的转化到左边,反复循环直至n<len以下是涉及到一些关于string类型的知识

2022-03-05 01:10:29 169

原创 洛谷P1990 覆盖墙壁

做完这题就感觉数学太神奇了,本来感觉很复杂的情况通过递推分类讨论,再化简竟然就得出那么简单的结论首先最后一块要么是2x1,要么是L,即两大类2x1的话有两种情况,竖放和横放,分别为f[i-1]和f[i-2]L的话就有无数种情况了,因为可以一直讨论f[0],且不用担心会重复上图帮助理解一开始看题解的时候开始就放了一个错:f[n-1]种情况,我却以为是f[n-1]+1,说明我前面的一些递推题还没有真正弄懂,这也导致了L情况的时候,x2半天理解不了int main() { int n;

2022-03-04 00:29:11 276

原创 洛谷P1036 [NOIP2002 普及组] 选数

bool ifsushu(int x) { for(int i=2;i<=sqrt(x);i++) if(x%i==0) return 0; return 1;}int a[25],n,k;long long c=0;void dfs(int k,int start,int sum) { if(!k) {if(ifsushu(sum)) c++;return;} for(int i=start;i<n;i++)//其实这里最开始是写i&

2022-03-03 00:28:53 173 1

原创 洛谷P1164 小A点菜

这道题对于还是菜鸟的我来说过于抽象了将菜从1到n依次排开,每道菜只有点和不点两种情况用f[i][j]表示前i个菜花费了j元那对于第i个菜,有两种情况:j<a[i];这种情况肯定没法点第i个菜,所以f[i][j]=f[i-1][j]j>=a[i];而这种情况就可以点或不点了,即f[i][j]=f[i-1][j]+f[i-1][j-a[i]]用两层循环,从1到n,从1到m,依次求出所有解【注意到抛开j,全是i和i-1之间的关系,这就意味着待会儿可以降维,但降维时要注意j是从后往前更新的

2022-03-02 00:52:59 300

原创 洛谷P2437 蜜蜂路线

又是斐波那契,而且需要高精!可能是因为有接近第1000个数了int f[1005][1005],length=1;int gaojing(int k) { for(int i=1;i<=length;i++) { f[k][i]=f[k-1][i]+f[k-2][i]; } for(int i=1;i<=length;i++) { if(f[k][i]>=10) f[k][i+1]++;//f[k][k+1]+=f[k][i

2022-02-28 23:41:33 304

原创 洛谷P1928 外星密码

string一个s,依次输入每个字符,进行判断后,加入s,最后输出也是一个递归,因为会有多重压缩,不过每次写那个递归函数的时候总是纠结返回类型,我怕太难了都直接定义一个全局变量,然用void反复操作该变量,最后输出。不过此题不需用全局变量,每次递归都要建立一个新的s,最后返回到上一层,加到上一层的s判断的话就三种可能:'['则递归,且单独储存下一个的数字']'则返回其他则加到该次递归的s上string jiema() { string s="",s1="";//初始化,s存放本次读取的

2022-02-28 00:22:39 161

原创 洛谷P1464 Function

记忆化搜索,说白了就是用一个数组存放之前已经计算过出的数据,避免每次都要重新计算一次long long int m[25][25][25]={0};long long int w(long long int a,long long int b,long long int c) { if(a<=0||b<=0||c<=0) return 1; if(a>20||b>20||c>20) return m[20][20][20]=w(20,20,20);

2022-02-26 10:26:54 168

原创 洛谷P1028 [NOIP2001 普及组] 数的计算

模拟(暴力递归)不行,后面数太大了,会超时所以得递推找规律,列出几条数据,观察2n和2n+1的情况相同,可以根据题意理解为相邻两个数,大一点的奇数和比他小一的偶数,不大于他们一半的数是相同的。观察偶数,其可以看成由上一个数➕它的一半的情况数相加。此题虽然好像脱离题目,直接找规律,但不管寻找还是理解规律都不必将题目完全独立出去。int main() { int n; cin>>n; long long f[1001]; f[0]=f[1]=1; fo

2022-02-25 21:03:16 719

原创 洛谷P1044 [NOIP2003 普及组] 栈

最开始是想模拟一个堆栈的进出,计算出输出序列情况总数但担心太复杂了,不确定是否能用数组模拟堆栈,根据之前的经验想着直接找规律,把该问题直接脱离出堆栈本身。显然不行,但其实我的思想还行,没有错的离谱,把两种思想结合起来:模拟堆栈并找规律本题数据有三个部分,队列区,栈区,输出区i表示队列区待排数,j表示栈里个数用一个二维数组来模拟一开始觉得太抽象,不好理解,而且递推(归)规律也有点抽象,但通过在草稿上演练一下就好懂了。就是从f[0][n](已知)到f[n][0](未知)的过程所有的i=0时都只有一

2022-02-24 21:42:49 307

原创 洛谷P1002 [NOIP2002 普及组] 过河卒

一个数组如果只有0,1做标记,就不一定要用int型,可以直接bool类型找到递推规律,最简单的是b[j]+=b[j-1],因为b[j-1]和b[j]还没有被更新,所以可以直接用,且数组只要设为b[25]大小就行。防止数组越界,所有的坐标+2用一个单独的数组a[25][25],记录是否为控制点int main() { int n,m,x,y; long long int b[25][25]={0};//b[25]={0}; bool a[25][25]={0}; cin

2022-02-23 12:04:13 804

原创 洛谷P1255 数楼梯

发现递推规律,为斐波那契,所以3开始,用for循环依次求出3~n的值而由于最后的结果会非常大,需要用到高精,一开始虽然也不是很懂什么意思,但其实就是把那么大的数(hundreds of 位)的每一位发到一个int数组里,从1到length依次相加,满10进1int gaojing[5005][5005],length=1;void feibo(int k) { for(int i=1;i<=length;i++) { gaojing[k][i]=gaojing[k-1]

2022-02-22 11:17:41 293

原创 洛谷P1205 [USACO1.2] 方块转换 Transformations

先建三个char数组,第一个存储原始图形,第三个存储目标图形,第二个存储经过六种变化后得到的待判定图形。找到旋转后与旋转前x,y坐标的规律注意:11->13 12->23 13->33char a[11][11],b[11][11],c[11][11];int n;bool myequal() { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(b[i][j]!=c[i

2022-02-21 10:50:11 1072

原创 洛谷P1320 压缩技术(续集版)

用一个数组装下所有输入,但用int数组好像不行用string数组,但是循环输入直接while(cin>>s)总是出问题用a[0].size()得出n,for循环输入int main() { /*int b[40001],a,count=0,c=0; bool flag=0; while(scanf("%1d",&a)) { if(a!=flag) flag=!flag; b[count++]=flag; }

2022-02-20 21:00:36 628

原创 洛谷P1319 压缩技术

用一个很长的一位数组储存01,这次不是先令所有的都为0,再将特定的变1了,而是一起赋值同时,注意到循环的核心是每次输入,而不是每行。int main() { int n; cin>>n; int b[n*n+1],s,count=0; bool flag=0;//注意不是int类型 while(cin>>s) { for(int i=0;i<s;i++) { b[i+count]=flag;

2022-02-19 23:50:11 374

原创 洛谷P1789 【Mc生存】插火把

bool overpass(int x,int y) { if(x<1||x>n||y<1||y>n) return 0; return 1;}//判断是否越界int main() { int n,m,k,x,y,count=0; cin>>n>>m>>k; int b[101][101]={0}; for(int i=0;i<m;i++) { cin>>x&g

2022-02-19 12:31:50 527

原创 洛谷P5731 【深基5.习6】蛇形方阵

这类问题,都是找前后两个数之间x,y之间的关联,比如x%n+1int main() { int n,b[10][10]={1},x=0,y=0; cin>>n; /*for(int i=2;i<=n*n;) { while(y<n-1&&b[x][y+1]==0) b[x][++y]=i++; while(x<n-1&&b[x+1][y]==0) b[++x][y]=i+

2022-02-17 13:08:57 372

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除