随笔分类 - 洛谷luogu
摘要:题目传送门 这道题其实直接做就好了,枚举每一个数,把这个数拆分一下就行了。 代码: #include<cstdio> using namespace std; int sum[10001],l,r; int main(){ for(int i=1;i<=10000;i++){ int k=i,cnt
        阅读全文
                
摘要:一看就不能用求根公式 首先,因为 \(a_i\) 很大,如果要高精度的话,时间复杂度都过不去。 那么,我们考虑把这个大数取模,这样如果弄出来是零,这个值就有可能是一个根。 这个模数最好是一个大质数,这样正确率会高一点 代码 #include<bits/stdc++.h> #define ll lon
        阅读全文
                
摘要:首先,如果 \(n\) 个都要选,那么显然,应该先把 \(b\) 值大的先选掉,这样浪费最小。 基于这种想法之上,我们就可以先按 b 排个序,然后 \(dp\) 用 \(f_{i,j}\) 表示在前 \(i\) 个中选了 \(j\) 个的最大金币数 所以递推式就十分显然,\(f_{i,j}=\max
        阅读全文
                
摘要:因为每一条边都要走个遍,所以 如果一个点的入度等于出度,那么在这个点一定不用走路。 如果一个点的入度小于出度,那么肯定还要从其他的点走路到这个点 如果一个点的入度大于出度,那么肯定还要从这个店走路到其他的点 现在,我们只要知道每一个点的入度减掉出度。 比如样例 很显然,让 \(②\) 和 \(①\)
        阅读全文
                
摘要:一看题目,搜索题啊。 首先,枚举排列,然后验证是否在同一条斜线上 设有两个点是 \(i,j\) 那么如果他们在从左上到右下↘的斜线上,那么一定满足$X_i-Y_i=X_j-Y_j$ 如果他们在从左下到右上↗的斜线上,那么一定满足$X_i+Y_i=X_j+Y_j$ 所以打出代码: #include<c
        阅读全文
                
摘要:一道哈希题。 因为只有两个关键字,直接用进制哈希。 然后存到一个数组里面,每次边更新答案边哈希 代码 #include<cstdio> using namespace std; int n; char a[100],b[100]; int get1(int i){//对城市开头的哈希 return 
        阅读全文
                
摘要:看数据可以猜测:这是一道状态压缩的动态规划题 没错。 我们用 \(f_i\) 表示在 \(i\) 状态下最少需要多少节点。 那么转移方程就是: \[ f_i=\min\limits_{j\&i=j}{f_j+f_{i-j}-lcp(i)} \] 这个 \(lcp(i)\) 就是在 \(i\) 状态下
        阅读全文
                
摘要:这个题目名称十分诡异。 然后我可以提供两种做法,复杂度一样,都是$O(n\log n)$的。 方法一 因为我们每一次使用魔法,就会让那个什么鬼畜的人物多走个$a_i$天,所以就可以贪心,每一次只要取大的就可以了,然后因为每一次都要加在一起看看够不够,所以就可以二分了。 代码 #include<bit
        阅读全文
                
摘要:我一开始就打出来了,可是忘记一个很重要的剪枝,就是如果当前的步数已经超过答案的步数就不用搜了,还有就是每一个点的每一种状态都只能走到一次(其实就是走到一个点,之前使用了相同的魔法已经到过这个点)那么也不用搜下去了。 代码 #include<bits/stdc++.h> using namespace
        阅读全文
                
摘要:一看,这个就是一个组合数学,如图所示 这样,很容易想到分类讨论,如果$x,y$在两侧和$x,y$在同侧。 如果是两侧的话,就可以枚举这两个位置的高度然后用组合数算出来就可以了。然后的话如果在同侧就不用管什么东西,把第$x$个位置到第$y$个位置的所有位置都是一样高的,就可以看成一个城市,剩下的左边$
        阅读全文
                
摘要:题面传送门 思路 因为最多只能两个物品一起,所以排个序,然后用两个指针,如果这两个可以,那就两个都要了,否则就只能要大的一个 代码 #include<bits/stdc++.h> using namespace std; int n,m; int a[30001]; int main(){ scan
        阅读全文
                
摘要:题面传送门 思路 因为跑和使用魔法不能同时执行,所以可以先处理光光使用魔法,然后再处理跑的情况 代码 #include<bits/stdc++.h> using namespace std; int m,s,t; int f[300001]; int main(){ scanf("%d%d%d",&
        阅读全文
                
摘要:题面传送门 思路 用结构体拍个序,然后输出就可以了。 代码 #include<bits/stdc++.h> using namespace std; int n; struct zj{ int x,y,z,sum,num; bool operator < (const zj &a)const{ if
        阅读全文
                
摘要:题面传送门 思路 一看嘛,不就是两遍$dp$,结果标签上写着个单调队列,我怎么想不出来如何单调队列啊。 于是,就只好打了暴力$dp$结果$A$了。 代码 #include<bits/stdc++.h> using namespace std; int n; int a[101]; int f1[10
        阅读全文
                
摘要:题面传送门 思路 我明知正解是枚举每一位是否进位然后用高斯消元来验证是否有解。 可是我偏不!!!! 我偏偏$dfs$。 剪枝剪枝+剪枝。 剪枝一:从低位的数开始搜索。 剪枝二:枚举每一个字母是什么数的时候从大到小枚举。 剪枝三:因为每一位最多只会进1,所以判断每一位如果不是这样的就直接$return
        阅读全文
                
摘要:题面传送门 思路 本蒟蒻表示:我只会用优先级队列做。 贪心:每一次只要取出最少的两堆合并就可以了。 代码 #include<bits/stdc++.h> using namespace std; int n; priority_queue<long long,vector<long long>,gr
        阅读全文
                
摘要:题面传送门 思路 $STL$真好,有两个函数: next_permutation() prev_permutation() 分别是求出数组的下一个排列,和上一个排列。 可以就返回$1$,如果无法操作了,返回$0$ 代码 #include<bits/stdc++.h> using namespace 
        阅读全文
                
摘要:题面传送门 思路 一道模拟题,注意下细节 代码 #include<bits/stdc++.h> int s,h; int main(){ int x; for(int i=1; i<=12; i++){ scanf("%d",&x); s=s-x+300; if(s<0){ printf("-%d"
        阅读全文
                
摘要:题面传送门 思路 因为只有唯一的顺序才完所有的花生,所以直接模拟即可 代码 #include<bits/stdc++.h> using namespace std; int n,m,t; int k; struct zj{ int x,y,sum; bool operator < (const zj
        阅读全文
                
摘要:题面传送门 思路 直接$dfs$,注意要输出后序,即为先左子树再右子树最后根 代码 #include<bits/stdc++.h> using namespace std; int n; string a; void dfs(int l,int r){ if(l<r){ dfs(l,(l+r)>>1
        阅读全文
                
 
                     
                    
                 
                    
                
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号