随笔分类 - 题解
题解
摘要:设f[i][j]是前i个水晶搭建成两座高度差值为j的较高的那座的高度,转移方程如下: 我用的不是f[i][j]=....,而是根据f[i][j]推出f[i+1][...],所以不好写方程,看代码吧:#include <stdio.h>#include <stdlib.h>int num[101];int f[101][200001];#define max(a, b) ((a)>(b)?(a):(b))int main(int argc, char **argv){ int i, j, sum = 0; int n; scanf("%d", &
阅读全文
摘要:f[i][j]代表j个乘号, 前i位数的最大值, 转移方程式: f[i][j] = max{f[k][j - 1] + num[k + 1][i]} (1 <= k < i),num[i][j]代表第i位数到第j位数组成的数字是多少。 代码如下:#include <stdio.h>#include <stdlib.h>typedef unsigned long long bignum;bignum f[41][31];bignum num[41][41];char str[42];#define max(a, b) ((a)>(b)?(a):(b))i
阅读全文
摘要:DP:f[i] = f[j] + 1 (1<= j < i, 且j是i的前缀.) 代码如下:#include <stdio.h>#include <string.h>#include <stdlib.h>char str[2001][501];int f[2001];int ans = 0;int main(int argc, char **argv){ int i, j; int n; scanf("%d", &n); for(i = 1; i <= n; i++){ scanf("%s",
阅读全文
摘要:别人都说直接输出一行中>=k的数目就可以了,但我觉得不保险。不过仔细一想,好像可以证明它是对的,但是我证明不好!所以我就直接写了一个记录性的搜索,代码如下:#include <stdio.h>#include <stdlib.h>int map[200][200];int n, k;int ans = 0;int count[200];int used[200];int search(int i){ int j, t = 0; if(count[i]){ return count[i] - 1; } if(used[i]){ return 1; } used[i]
阅读全文
摘要:我直接暴力搜的,还有一个强连通分量的算法,琢磨一下,明天写:#include <stdio.h>#include <stdlib.h>#define INF 0xFFFFFFFint map[200][200];int count[200];int group[200];int n;void mark(int i, int k){ int j; if(group[i] == k){ return; } group[i] = k; for(j = 0; j < n; j++){ if(map[i][j] != INF && map[j][i] !=
阅读全文
摘要:DP,DP方程好复杂,不知道怎么说的好,代码里分解吧:#include <stdio.h>#include <stdlib.h>#define max(a, b) ((a)>(b)?(a):(b))int g[300001][2], f[300001];int main(int argc, char **argv){ int i, min = -1; int m, s, t; scanf("%d%d%d", &m, &s, &t); g[0][0] = m; for(i = 1; i <= t; i++){ if(
阅读全文
摘要:因式分解神马的,具体上代码:#include <math.h>#include <stdio.h>#include <stdlib.h>int a0, a1, b0, b1;int prim[20000], num[20000], end;int ans[200000], len;int gcd(int a, int b){ int t; while(b != 0){ t = a % b; a = b; b = t; } return a;}void dfs(int now, int pro){ int i; if(now == end){ ans[len+
阅读全文
摘要:题目中的原话:(**注意**:在任意一层的第一段也可以走到本层的最后一段或上一层的最后一段)。 好恶心的题目,就是一个BFS,一个个搜,但是又类似于DP,不知道怎么形容的好,反正很猥琐。 最后就这样吧,我想说,好好学OI,拿IOI冠军,我要报送。#include <stdio.h>#include <stdlib.h>#define MAX 100000#define deal(a, b) deal_(a, b, i, j)int num[1001][1001];int f[1001][1001];int used[1001][1001];int n;struct qu
阅读全文
摘要:我也不知道为什么,负数的进制就是这么写的,反正记住就是,如果余数是负数,那就加上base,然后再用n-新余数 再除以base。 代码如下:#include <stdio.h>#include <stdlib.h>#define MAX 10000int ans[MAX];int start;const char str[] = "0123456789ABCDEFGHIJKLNNOPQRSTUVWXYZ";int main(int argc, char **argv){ int i; int n, base; int r; while(scanf(&q
阅读全文
摘要:题解,转自:http://zhurui250.blog.163.com/blog/static/137270520201012410434807/【问题转述】给出m1,m2以及若干个个si,求si^a mod m1^m2=0中a的最小值。若无解,输出-1。【分析】由于数据太大,根本不能直接计算,但是我们可以通过因式分解来找到突破点。当m1分解出一个因数而s[i]没有时,这种情况肯定无解,当m1和s[i]对此因数各有一定数量时,我们可以根据这个算出让此因数得到整除的a最小值(可能不是所有因数中最优答案,取所有因数答案最大的)设x为m此因数的个数,y为s[i]此因数的个数,则a=x div y;
阅读全文
摘要:纯模拟,考虑0啊,1啊,-1啊等的特殊情况就行了。。。 代码如下:#include <stdio.h>#include <stdlib.h>const char xishu[2][4] = {"%+d", "%d"};void output(int a, int b, int *c){ if(a == 0){ return; } if(b == 0){ printf(xishu[*c], a); }else if(abs(a) == 1){ if(*c){ if(a == -1){ printf("-"); }
阅读全文
摘要:就用DFS吧,然后注意剪枝和环就行,代码如下:#include <stdio.h>#include <stdlib.h>int rode[80000], next[80000];int time[80000], tili[80000];int tail;int head[5000];int n, m;int have, ans = 0xFFFFFFF;int use, tmp;int t;void add(int a, int b, int c, int d){ tili[tail] = c; time[tail] = d; rode[tail] = b; next[t
阅读全文
摘要:直接暴力搜索就是,没太多的算法,不过我要说的是,题目的数据根本没按照题目的范围来,比题目说的范围要大一些……鄙视出题者,,有10 4的数据,所以根据数据,我定义的MAX是427。 代码如下:#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAX 427int ans[11], max;int s[11];int n, k;int count(int *need){ int i; for(i = 1; i <= MAX; i++){ if(need[i] > n){ b
阅读全文
摘要:跟8年前NOIP 2000 方格取数的题目几乎一样,不多解释了,代码:#include <stdio.h>#include <stdlib.h>#define min(a, b) ((a)<(b)?(a):(b))#define max(a, b) ((a)>(b)?(a):(b))int map[51][51];int f[100][51][51];int main(int argc, char **argv){ int i, j, k, c; int m, n; scanf("%d%d", &m, &n); for(i
阅读全文
摘要:这算什么算法呢?? 模拟吧,反正很简单,代码:#include <stdio.h>#include <stdlib.h>int num[2000] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};int ans;int main(int argc, char **argv){ int i, j; int n; scanf("%d", &n); n -= 4; for(i = 10; i < 2000; i++){ num[i] = num[i / 10] + num[i % 10]; } for(i = 0; i &l
阅读全文
摘要:双线程动态规划,f[i][j][k]代表移动i次,两个点的横坐标分别是j, k,转移方程如下: f[i][j][k] = max(f[i - 1][j][k],f[i - 1][j][k - 1],f[i - 1][j - 1][k],f[i - 1][j - 1][k - 1]) 代码如下:#include <stdio.h>#include <stdlib.h>int map[11][11];int f[20][11][11];#define max(a, b) ((a)>(b)?(a):(b))int main(int argc, char **argv){
阅读全文
摘要:最开始写的伪代码如下:寻找当前油量能到达的最便宜的加油站 如果找到了,那就开过去加油。 如果找不到, 那就寻找最近的比本站便宜的站点 找到的话就加油刚好开过去 找不到的话就寻找次优站点,充满油开过去 如果找不到任何站点,那就输出No Solution 但是发现可以优化结构,就又写了一个:寻找距离当前站最近的比当前站便宜的站点 如果找到了,油量够就直接开过去,油量不够就冲到刚好可以开过去 如果找不到,就到前面找一个充满油量能到得了的最便宜的站点,充满油开过去。 如果加满油找不到任何站点,那就输出No Solution 代码如下:#include <stdio.h>#include &
阅读全文
摘要:纯模拟吧~~细节不阐述了,代码如下:#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>#define MAX 100001int str[MAX];int tmp[MAX];int len;int k;int huiwen(void){ int i = 0, j = len - 1; while(i < j){ if(str[MAX - 1 - i] != str[MAX - 1 - j]){ return 0; } i++, j--; } r
阅读全文
摘要:暴力搜就可以了,枚举每一个点放进第j个矩形里面,然后保存最小值就可以了,代码如下:#include <stdio.h>#include <stdlib.h>#define oo 0xFFFFFFFstruct dot{ int x, y;}dots[50];struct ret{ struct dot l, r;}rec[4];int n, k;int ans = oo;int check_(int i, int j){ if(rec[i].l.x == oo || rec[i].l.y == oo || rec[i].r.x == -oo || rec[i].r.y
阅读全文
摘要:挺好的题目,以后记住,当出现初始状态和目标状态求最短路径的时候就用双向DFS,速度快很多!!! 双向BFS的资料:http://www.cnblogs.com/yylogo/archive/2011/07/25/double-bfs.html 代码如下:#include <stdio.h>#include <string.h>#include <stdlib.h>struct { char str[401]; int sep;}q1[20000], q2[20000];int h1, r1, h2, r2;char s1[6][21], s2[6][21];
阅读全文
浙公网安备 33010602011771号