
OJ与算法
苗尼玛乔
直到青春一定程度地浪费,才觉得可贵
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
背包问题模板
转载至此链接int v,j; //v:总容量 int dp[Maxv]; //c:体积 w:价值 n:数量 void zobag(int c,int w)//01背包 { for(j=v;j>=c;j--) dp[j]=Max(dp[j],dp[j-c]+w);}void combag(int c,int w)//完全背包 { for(j=c;转载 2016-05-08 21:57:28 · 595 阅读 · 0 评论 -
hdu 1004
#include<stdio.h>#include<string.h>int main(){ char str[1000][16]; int n; while(scanf("%d",&n),n!=0){ char temp[16];int i,j;int count[1000];int pos=0; memset(count,0,size原创 2016-07-22 17:32:18 · 245 阅读 · 0 评论 -
hdu 1005
//res[i]=res[i-1]+res[i-2];//res[i-1],res[i-2]的可能只有7种情况,0123456,所以res[i]最多49种情况#include<stdio.h>int A,B;int res[60]; int main(){ int n,i; while(scanf("%d%d%d",&A,&B,&n),A!=0&&B!=0&&n!=0){原创 2016-07-23 12:46:50 · 221 阅读 · 0 评论 -
钱币组合方式
假设我们有无限多的1元,2元,5元,10元,20元,50元,100元,200元的钱币,那么为了组合成一个200元的钱币,共有多少种组合方式? 比如说: 200 = 1×100+1×50+2×20+1×5+1×2+3×1。 因为有了1元的钱币,这就使我们组成的任何不足200的数字可以整合为200。 为了说明问题,我们来观察这样的一个类似的小问题,用1元,2元,5元来组成5元。 如果原创 2016-11-21 16:28:53 · 4018 阅读 · 0 评论 -
Dilworth定理
偏序集的两个定理: 定理1) 令(X,≤)是一个有限偏序集,并令r是其最大链的大小。则X可以被划分成r个但不能再少的反链。 其对偶定理称为Dilworth定理: DIlworth定理 定理2) 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小。则X可以被划分成m个但不能再少的链。反链:关系相反的链(如<=的相反为>)例如:1 5 6 2 3 4 反链:最长递减子序列为6 2转载 2016-12-25 15:53:33 · 718 阅读 · 0 评论 -
KMP(无回溯模式匹配)模板
int *get_next(char *p){ int len=strlen(p); int *next=(int*)malloc(len*sizeof(int)); next[0]=-1; int i,j; for(j=1;j<len;j++) for(i=next[j-1];;i++) if(p[j]==p[i+1]){转载 2017-01-31 15:31:27 · 645 阅读 · 0 评论 -
nyoj26_孪生素数(筛选法求素数)
原题链接》》》筛选法求素数: 从3开始将素数的倍数依次标记,被标记的即为非素数for(i=3;i<Nmax;i++) if(!prime[i]) for(j=i+i;j<Nmax;j+=i) prime[j]=1;**AC代码:**#include<stdio.h>#define Nmax 1000001bool prime[Nm原创 2017-01-30 23:03:24 · 468 阅读 · 0 评论 -
nyoj7_街区最短路径问题
思路:这个题目是求一个点 到平面整点集的最短曼哈顿距离。等价于2次求一维 数轴上的y=|x-x0|+|x-x1|......|x-xn| 求最小的y的值。分析:1.当数轴上只有2个点,那么到2个点最短距离是两个点所构成的线段长度, 此时x的取值范围[x0,x1](闭区间).2.当数轴上只有3个点x0,x1,x2, 那么到3个点最短距离是除去中间那个点所构成的线段长度,此时x=x1。AC代码:#转载 2017-02-01 21:13:15 · 270 阅读 · 0 评论 -
nyoj32_组合数
原题链接》》》简单的dfs:#include<stdio.h>int n,r;int num[11];void dfs(int cur,int k){ if(cur+k<=2) return ; if(cur==r){ for(int i=0;i<r;i++) printf("%d",num[i]); printf("\n");原创 2017-01-30 23:21:52 · 278 阅读 · 0 评论 -
nyoj38_布线问题
原题链接》》》1.prim算法实现: 参考链接》》》**AC代码:**#include<stdio.h>#include<string.h>#define Nmax 501#define inf 0x3f3f3f3fint map[Nmax][Nmax];int prim(int v){/*low[j]记录以j为终点的边的最小值且边的起点是存在于已访问点集*/ int lo原创 2017-01-18 19:36:27 · 237 阅读 · 0 评论 -
nyoj28_大数阶乘
原题链接》》》模拟手算乘法的过程: abc*de: c*de+l对10求余=》c 进位l=c*de+l/10; ... 最后一步的进位l可能是多位数,所以分为个位数循环往数组后面存。。。#include<stdio.h>int a[16350];int main(){ int i,j,l; int len=1;原创 2017-02-04 15:01:55 · 217 阅读 · 0 评论 -
nyoj469_擅长排列的小明2
原题链接》》》最初的想法是深搜,超时#include<stdio.h>int n;int count;bool vis[56];int num[56];void dfs(int i,int m){ num[i]=m; if(m-num[i-1]>2||num[i-1]-m>2) return ; if(i==n){ count++;return ;原创 2017-01-09 16:38:30 · 327 阅读 · 0 评论 -
大数相加(hdu 1002)
#include<stdio.h>#include<string.h>int main(){ int T,k;k=1; scanf("%d",&T);int n=T; while(T--) { char A[1001]; char B[1001]; int C[1001]; int i,j,pos,j原创 2016-07-09 12:55:07 · 316 阅读 · 0 评论 -
克鲁斯卡尔Kruskal
寻找直接或间接连通所有城市的,最小费用的道路集合的问题,就是寻找最小生成树的问题.#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define MAX 100/* 定义边(x,y),权为w */typedef struct{ int x, y; int w;}edge;edge e[MAX];/* ran原创 2016-06-10 14:22:22 · 317 阅读 · 0 评论 -
矩阵乘法
1.从定义触出发//intput:矩阵A,矩阵B(假设都为n*n)//output:矩阵Cfor(int i=1;i<=n;i++)for(int j=1;j<=n;j++){ C[i][j]=0; for(k=1;k<=n;k++) C[i][j]=C[i][j]+A[i][j]*B[i][j];} 2.Strassen算法 考虑用分治法计算矩阵乘原创 2016-06-08 09:44:44 · 265 阅读 · 0 评论 -
字典树...(eg.hdu 1251)
hdu题目链接(可以用简单的字符串操作写,更简单…这里是为了学一下字典树的知识点)>_<又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。字典树与字典很相似,当你要查一个单词是不是在字原创 2016-05-23 16:45:41 · 280 阅读 · 0 评论 -
kmp
kmp看不懂啊!先放着再说!#include<stdio.h>#include<string.h>int next[10001];void make_next(char sstr[],int ls){ next[0]=-1; int j=0;int k=-1; while(j<ls-1) { if(k==-1||sstr[j]==sstr[k]翻译 2016-05-25 13:45:10 · 180 阅读 · 0 评论 -
hdu 1754(i hate it)
hdu原题链接#include<stdio.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define MM 200001int max[MM<<2];int Max(int a,int b){ return a>b?a:b;}void PushUp(int rt){ max[rt]=Max(max[rt<<1转载 2016-05-25 14:01:48 · 203 阅读 · 0 评论 -
hdu 1166 敌兵布阵
hdu原题链接#include<stdio.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 55555int sum[maxn<<2];void PushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int r转载 2016-05-25 14:09:01 · 185 阅读 · 0 评论 -
二分搜索模板
int Bsearch(int i,int j,int key){ while(i<=j){ int k=(i+j)/2; if(key==L[k]) return k; else if(key<L[k]) return Bsearch(i,k-1,key); else retu原创 2016-06-01 21:56:45 · 236 阅读 · 0 评论 -
邻接表建图+深度遍历+判断连通性
#include<stdio.h>#include<stdlib.h>#define Max 10typedef struct Node{ int ver; struct Node*next;}VexNode;struct Adj{ VexNode*next;}; Adj adj[Max];int visit[Max];void depth(int start原创 2016-06-02 22:00:47 · 2384 阅读 · 0 评论 -
广度优先遍历
#include<stdio.h>#include<stdlib.h>#define N 10int visit[N];typedef struct { int elem[N]; int front; int rear;}Seqqueue;void initSeq(Seqqueue *Q){ Q->front=Q->rear=0;}int Ente原创 2016-06-05 14:58:23 · 247 阅读 · 0 评论 -
拓扑排序(广度遍历)
这里的邻接表建图采用的是头接法…#include<stdio.h>#include<stdlib.h>#define N 20int k;int visit[N];typedef struct node{ int ver; struct node*next;}VexNode;struct Adj{ VexNode*next;};void InitMap(Adj原创 2016-06-05 17:09:38 · 672 阅读 · 0 评论 -
回溯算法的形式
//编写一个有用的回溯算法的关键是编写一个高效的界定函数,他可以在搜索树消除很多不可能的节点 backtrack(n){ rbacktrack(1,n);} rbacktrack(k,n){ for each x[k]-->S if(bound(k)) if(k==n) {原创 2016-06-05 22:51:09 · 323 阅读 · 0 评论 -
哈密尔顿环路问题
额的代码:#include<stdio.h>#include<string.h>#define N 11int visit[N];int adj[N][N];int M;int path_OK(int cur,int hamilton[]){ if(visit[hamilton[cur]]) return 0; if(cur<M) return adj[原创 2016-06-06 20:42:30 · 1687 阅读 · 0 评论 -
归并排序
#include<stdio.h>#define N 10void merge(int a[],int i,int m,int j){ int p=i; int q=m+1; int r=i; int C[N]; while(p<=m&&q<=j) { if(a[p]<=a[q]) C[r++]=a[p++]; e原创 2016-06-07 23:24:23 · 283 阅读 · 0 评论 -
nyoj214_单调递增子序列(2)二分查找 nlogn
原题链接》》》描述:子序列存储在ans数组(只是数组长度等于真正的单调子序列) num[i]依次与ans末尾比较,num[i]大则加到ans数组后面 num[i]小则在ans数组中找一个数a(a是比num[i]大的数中最小的一个)替换掉 例如: num数组:1 9 10 5 11 2 13 ans数组的变化: 1 1 9 1 9 10 1 5 10 1 5 10 11 1 2原创 2017-01-08 23:19:42 · 394 阅读 · 0 评论 -
nyoj236_心急的c小加
原题链接》》》#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct{ int l,w;}bang;int cmp(const void*a,const void*b){ bang*c=(bang*)a; bang*d=(bang*)b; if(c->l==d->l)原创 2016-12-25 16:02:20 · 273 阅读 · 0 评论 -
nyoj_37 回文字符串
原题链接》》》解法描述: 输入字符串为s,将s逆置存到s1,然后求出s与s1的最长公共子序列(dp),最后用s长度len-dp,所得即为所求!!!求最长公共子序列的算法》》》#include<stdio.h>#include<string.h>char s[1005];int dp[1005][1005];void str_ver(char str[],char str1[]){原创 2016-11-24 11:50:12 · 309 阅读 · 0 评论 -
nyoj36_最长公共子序列
原题链接》》》 参照这位大神写的blog才看懂的》》》我来说下自己的理解: 两个字符串s1= ????# 和s2= ???# ,如果#和#相等,则s1和s2的最长子序列等于???? 和 ???的最长子序列+1,如果不等,则s1和s2的最长子序列等于Max(????#与???的最长子序列,????与???#的最长子序列);这大致就是状态转移方程了!!!#include<stdio.h>#incl原创 2016-11-21 19:05:48 · 355 阅读 · 0 评论 -
nyoj6_喷水装置1
原题链接》》》大概是这么个意思: #include<stdio.h>#include<stdlib.h>#include<math.h>int cmp(const void*a,const void*b){ return *(double*)b>*(double*)a;/*这个地方写成 *(double*)b-*(double*)a 害的我调了一个多小时,烦!!!*/}doub原创 2016-12-02 17:25:56 · 285 阅读 · 0 评论 -
nyoj14_会堂安排问题
原题链接》》》#include<stdio.h>#include<stdlib.h>typedef struct activity{ int b; int e;}act;act A[10001];int cmp(const void*a,const void* b){ act*c=(act*)a; act*d=(act*)b; return c->e原创 2016-11-30 14:43:37 · 266 阅读 · 0 评论 -
nyoj10_skiing
原题链接》》》状态转移方程dp[i][j]=Max(dp[i][j],四周比自己小的dp值+1);#include<stdio.h>#include<string.h>int num[101][101];int dp[101][101];int dr[4][2]={ {0,-1},{0,1},{-1,0},{1,0}};int R,C;int Max(int a,int b){原创 2016-11-29 18:09:10 · 224 阅读 · 0 评论 -
nyoj-一笔画问题(欧拉图+并查集)
nyoj原题#include<stdio.h>#define Max 1001int father[Max];int rank[Max];void make_set(int x){ father[x]=x; rank[x]=0;}int find_set(int x){ if(father[x]!=x) father[x]=find_set(father翻译 2016-04-23 11:34:15 · 353 阅读 · 0 评论 -
nyoj 117 求逆序数
———-nyoj 117 求逆序数 1.归并排序:#include<stdio.h>int A[1000001],T[1000001];long long count=0;void merge_s(int *A,int x,int y,int *T){ if(x==y) return ; int m=(x+y)>>1; merge_s(A,x,m,T); m翻译 2016-04-19 17:21:18 · 500 阅读 · 0 评论 -
最短路径问题 eg.城市平乱
南阳oj里的一道题:115刚开始的弗洛伊德算法(超时的):#includeint dist[101][1001];int main(){int T,i;scanf("%d",&T);while(T--){int N,M,P,Q;int ni[101];scanf("%d%d%d%d",&N,&M,&P,&Q);for(i=0;i<N;i++)scanf("%d"原创 2016-04-18 15:36:27 · 430 阅读 · 0 评论 -
士兵杀敌 1-5
一:nyoj原题链接#include<stdio.h>#include<stdlib.h>int main(){ int n,m; scanf("%d%d",&n,&m); int *num;int i;int a,b; long long *sum; num=(int*)malloc(n*sizeof(int)); sum=(long long转载 2016-05-25 13:19:12 · 424 阅读 · 0 评论 -
南阳ACM 找球号(2)
1.位储存 一个short类型有16位,可以存放16个编号的是否存在情况!!#includeshort num[6250005];int main(){int n;scanf("%d",&n);char str[5];int m,mm;while(n--){scanf("%s%d",str,&m);if(str[0]=='A')while(m--){原创 2016-04-16 21:50:06 · 359 阅读 · 0 评论 -
nyoj27-水池数目(并查集||暴力递归)
1.用并查集将相邻水池union(求连通分支!)#include<stdio.h>#define Max 10005int father[Max];int map[101][101];void make_set(int n){ for(int i=1;i<=n;i++){ father[i]=i; }} int find_set(int n){原创 2016-04-27 11:02:21 · 295 阅读 · 0 评论 -
nyoj58_最少步数
原题链接》》》#include<stdio.h>#include<string.h>bool map[9][9]={ {1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,1,0,1}, {1,0,0,1,1,0,0,0,1}, {1,0,1,0,1,1,0,1,1}, {1,0,0,0,0,1,0,0,1}, {1,1,0,1,0,原创 2016-12-06 20:04:07 · 275 阅读 · 0 评论