摘要:包含插入和询问的线段树,简化版,据说这道题暴力也能过。Description现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。 限制:L不超过当前数列的长度。 2、 插入操作。 语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。 限制:n是非负整数并且在长整范围内。 注意:初始时数列是空的,没有一个数。Input第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),
阅读全文
摘要:http://www.lydsy.com/JudgeOnline/problem.php?id=1263Description从文件中读入一个正整数n(10≤n≤31000)。要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。Input只有一个正整数: n (10≤n≤31000)Output第1行输出一个整数,为最大乘积的位数。 第2行输出最大乘积的前100位,如果不足100位,则按实际位数输出最大乘积。 (提示:在给定的范围内,最大乘积的位数不超过5000位)。Sample Input13S
阅读全文
摘要:直接通过判断出度和入度确定,这题的结束标志是两个负数(不一定是-1),输入中含有 0 0 这组数据(判为no),最后一组数据后面要留换行,否则PE;http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?cid=1304&pid=1003&ojid=0View Code # include <cstdio># include <cstring># define N 20bool ok;int in[N], out[N];void init(void){ ok = false; memset(in,
阅读全文
摘要:不知道有没有更好的做法(省空间,省时间)。http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1002&ojid=0&cid=1304&hide=0# include <cstdio># include <cstring># define N 100000 + 5int p[N];bool ok, vis[N];void init(void){ ok = false; for (int i = 1; i < N; ++i) p[i] = i; memset(vis, fa
阅读全文
摘要:# include <cstdio># include <algorithm>using namespace std;# define N 100 + 5# define M 5000 + 5int n, m;int p[N];int u[M], v[M], w[M], r[M];void read_graph(void){ int tmp; m = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) { scanf("%d", &tmp); if (i <
阅读全文
摘要:无向图,求从1出发到n再回到1的最短路,不能重复走同一条边。错误思路:先求出1到n的最短路,删去经过的边,再求一次最短路,相加,容易找到反例。WA# include <cstdio># include <cstring># include <queue># include <algorithm>using namespace std;# define N 100 + 5# define INF 0x3c3c3c3cint n, m;int pre[N], d[N];int w[N][N];void destory(void){ for (int
阅读全文
摘要:SPFA,2RE,无向图的边数为题目描述的两倍。# include <cstdio># include <cstring># include <queue>using namespace std;# define N 20000 + 5# define M (50000 + 5) * 2# define INF 550000000int n, m, src, des;int first[N], d[N];bool inq[N];int u[M], v[M], w[M], next[M];void read_graph(void){ scanf("%
阅读全文
摘要:第一道 SPFA, 1A。Problem Description在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?Input输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<
阅读全文
摘要:bfs,需要注意0和N是可以到达的,除此之外也可以到达,但实际上不可能更优,因为超过这个范围表明需要回退,回退的步数超过2时,完全可以多走几步再翻倍,结果更优。# include <cstdio># include <queue># include <cstring>using namespace std;# define MAXN 100000 + 5# define N 100000 + 1int n, k;char vis[MAXN];int d[MAXN];int bfs(void){ queue <int> Q; memset(vis,
阅读全文
摘要:DFS,要求输出字典序最小的,注意扩展方向。# include <cstdio># include <cstring># define N 26 + 5const int dx[] = {-1, 1,-2, 2,-2, 2,-1, 1};const int dy[] = {-2,-2,-1,-1, 1, 1, 2, 2};int p, q, cnt;bool finished;char solu[N][2];char vis[N][N];void dfs(int x, int y){ solu[cnt][0] = x, solu[cnt][1] = y; if (cnt
阅读全文
摘要:bfs,使用C++的queue,300ms。# include <cstdio># include <cstring># include <queue>using namespace std;const int dx[] = {1,1,-1,-1,2,2,-2,-2};const int dy[] = {2,-2,2,-2,1,-1,1,-1};struct Pos{int x, y, d;};char s[5], g[5];int sx, sy, gx, gy;int bfs(void){ queue <Pos> Q; Pos cur, nst
阅读全文
摘要:dfs,统计最多多少个相邻(有公共边)方块。# include <cstdio># include <cstring># define N 100 + 15int n, m, k;char lake[N][N];int ans, cur;const int dx[] = {0,1,0,-1};const int dy[] = {1,0,-1,0};void dfs(int x, int y){ lake[x][y] = 0, ++cur; for (int i = 0; i < 4; ++i) { int nx = x + dx[i]; int n...
阅读全文
摘要:给出S和T个整数集合,分别含有n和m个元素(n<=m<=500),问 的最小值。如果a>b && c>d,有|a-c|=|b-d| >= |a-d| + |b-c|(不妨设c>a,然后对d与a,b的大小讨论,可以去掉绝对值符号证明),要对S和T排序。动态规划,if ( i == j) f[i,j] = f[i-1, j-1] + abs( s[i] - t[j] ) ,所以边界条件有 f[0,0] = 0;if (j > i) f[i, j] = min( f[i, j-1], f[i-1, j-1]+abs( s[i] - t[j]
阅读全文
摘要:根据题目描述,可以知道 1 和 8 只能放在 C 和 F 两个位置,固定好 1 和 8 后,2 和 7 也就固定了,剩下的就是枚举了;View Code # include <cstdio>const int tab[][8] = { {7, 3, 1, 4, 5, 8, 6, 2}, {7, 4, 1, 3, 6, 8, 5, 2}, {2, 5, 8, 6, 3, 1, 4, 7}, {2, 6, 8, 5, 4, 1, 3, 7}};int a[9];voi...
阅读全文
摘要:这道题暴力秒过,以前在ZOJ上见过,当时不会,还以为不剪枝铁定超呢,结果纯暴力就过了。# include <cstdio># include <cstring># define N 4 + 3int n, ans;char g[N][N];bool check(int x, int y){ int i = x; if (g[x][y] != '.') return false; while (i <= n) { if (g[i][y] == 'X') break; else if (g[i][y] == (i-1)*n+y) ret
阅读全文
摘要:这道题的剪枝:奇偶性,曼哈顿距离类型的。不剪会超时。# include <cstdio># include <cstring>using namespace std;# define N 7 + 3# define ABS(x) (((x)>0)?(x):(-(x)))int si, sj, gi, gj;int n, m, T;char g[N][N];bool vis[N][N];bool finished;const int dir[][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};void dfs(int x, int y, in
阅读全文
摘要:这道题如果用 DFS 必须剪枝:剪掉重复的组合。DFS 枚举了所有的排列,实际上这道题只需要组合。View Code # include <cstdio># include <cstring># define N 20 + 5int ans;int n, k, vMax, v[N], w[N];bool vis[N];void dfs(int cur, int sum, int cnt, int weight){ if (weight > vMax) return ; if (cnt == k) ans = (sum > ans ? sum : ans);
阅读全文
摘要:HINT 误导人,水题。View Code # include <cstdio># include <cstring># define N 15 + 5int n, ans;int f[N][N];bool vis[N];void dfs(int cur, int cnt, int t){ if (cnt > ans) ans = cnt; for (int i = 0; i < n; ++i) if (vis[i] == false && f[cur][i] >= t) { vis[i] = true; dfs(i, cnt+1, f
阅读全文
摘要:DFS 其实会超时的,打表。# include <cstdio># include <cstring># define N 10 + 5int n, ans;int solu[N];bool vis[N];void dfs(int cnt){ if (cnt == n) { ++ans; return ; } bool ok; for (int i = 1; i <= n; ++i) if (vis[i] == false) { ok = true; for (int j = 1; j <= cnt; ...
阅读全文
摘要:注意:标号后面是两个空格。# include <cstdio># include <cstring># include <algorithm>using namespace std;int n, m, adj[21][3];bool vis[21];int solu[22];void dfs(int cur, int cnt){ int t; for (int i = 0; i < 3; ++i) { t = adj[cur][i]; if (cnt == 20 && t == m) { printf("%d: ...
阅读全文
摘要:这道题目有问题,4WA :注意:对于每组测试,Lele都是在站点0拉上乘客的。最后看了题解,改了初始状态 AC 的。View Code # include <cstdio># include <cstdlib># include <cstring># define N 30 + 5int n, k;int g[N][N], des[N], min;bool vis[N];int cmp(const void *x, const void *y){ return *(int*)x - *(int*)y;}void dfs(int cnt, int u, int
阅读全文
摘要:这道题放在 DFS 里不太合适,我刚开始就想到了 DP 却没写,DFS 超时后看了题解才发现就是记忆化搜索(白书认为记忆化就是DP);1TLE 2WA,把 lens 写成了 lent 后来才发现的。View Code # include <cstdio># include <cstring># define N 200 + 10bool finished, f[N][N];int lens, lent;char s[N], t[N], g[2 * N];void dfs(int p, int q, int cnt){ if (finished) return; if (
阅读全文
摘要:不含回溯,看了标程后 AC 的,标程的代码很短,处理相同解的方法比较好。View Code # include <cstdio># define N 12 + 5bool find;int t, n, a[N], solu[N];void dfs(int sum, int p, int cnt){ if (sum > t) return ; if (sum == t) { find = true; printf("%d", solu[0]); for (int i = 1; i < cnt; ++i) print...
阅读全文
摘要:有向图的DFS,不能包含回溯,会爆栈的。View Code # include <cstdio># include <cstring># define N 26bool finished, vis[N];char g[N][N];void dfs(int u){ for (int i = 0; i < N; ++i) { if (u != i && g[u][i]) { if (vis[i]) return; if (i == 'm'-'a') {finished = true; return ;} ...
阅读全文
摘要:View Code # include <cstdio># include <cstring># define N 10 + 5int r, c, s, d[N][N];char grid[N][N];void init(void){ scanf("%d", &s); for (int i = 1; i <= r; ++i) { scanf("%s", grid[i]+1); memset(d[i]+1, 0, sizeof(d[i][0])*c); }}void solve(void){ int x, y, t;
阅读全文
摘要:View Code # include <cstdio># include <cstring># define N 20 + 5char ptab[25] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0};int n, solu[N];bool vis[N];void dfs(int cnt){ if (cnt...
阅读全文
摘要:DFS 题目,剪枝比较重要,这里使用的是把重复的方块只记录一次,用 num[] 保存它的数目。# include <cstdio># include <cstring># define N 25 + 2bool finished;int n, m, t[N][4], num[N], ans[N];void dfs(int cnt){ if (cnt == n*n) {finished = true; return ;} int x = cnt/n + 1, y = cnt%n + 1; int left = cnt, top = cnt+1-n; for (int i
阅读全文
摘要:模拟题,给出一个 n×n 的字符块的两个状态(分别为初始态和目标态)和几种操作,问目标态最少是由初始态的哪个操作完成的,WA 3 次。/*PROG: transformLANG: C++*/# include <cstdio># include <cstring># define N 10 + 5void print(char s[][N], int n){ for (int i = 0; i < n; ++i) puts(s[i]);}/* rotate 90 degrees clockwise */void rotate(char s[][N], i
阅读全文
摘要:直接暴力也可,用的二分搜索+枚举,文件输入的调试了很久,后来不知道怎么就对了。二分的是写成求最小符合条件的下标;/*PROG: namenumLANG: C++*/# include <cstdio># include <cstring># include <cstdlib># define N 5000 + 10# define LEN 20int len[N];char s[N][LEN];char tab[30];void build(void){ for (int i = 'A'; i < 'S'; ++i) t
阅读全文
摘要:给出 n 和 s (十进制),打印 s 后面 n 个在 2-10 进制中至少两个进制下为回文数的十进制表示。/*PROG: dualpalLANG: C++*/# include <cstdio># include <cstring>int n, s;void strRev(char *s){ char ch; int len = strlen(s), mid = len / 2; for (int i = 0; i < mid; ++i) ch = s[i], s[i] = s[len-1-i], s[len-1-i] = ch;}void to(int ba.
阅读全文
摘要:给出一个数 n(十进制),求出 1-300 范围内所有平方(n 进制)为回文串的数,并打印。/*PROG: palsquareLANG: C++*/# include <cstdio># include <cstring># define N 300void strRev(char *s){ char ch; int len = strlen(s), mid = len / 2; for (int i = 0; i < mid; ++i) ch = s[i], s[i] = s[len-1-i], s[len-1-i] = ch;}void to(int bas.
阅读全文
摘要:把所有区间(如果能)合并起来,求最长连续区间长度和最长间隔长度(两个区间之间,如果只有一个区间为0);/*PROG: milk2LANG: C++*/# include <cstdio># include <cstdlib># define N 5000 + 10struct val{ int s, t;} a[N];int n;int cmp(const void *x, const void *y){ val *p = (val*)x; val *q = (val*)y; if (p->s == q->s) return p->t - q->
阅读全文
摘要:这道题理解了题目的含义就很简单了;如果题目改成每次只统计一端,遇到不同时开始统计另一端,并且只有相邻两次统计的(可以转化)为同一种颜色时,才能累加,难度会很高,可能要DP了;/*PROG: beadsLANG: C++*/# include <cstdio># include <cstring># define N 350 + 10int n;char s[N];int count(char *s, int k){ int ret = 0; int i = k; int j = (k-1+n) % n; char cur; while(ret < n &&
阅读全文
摘要:这道题挺不好写的,题目是说给出一个年份范围,统计这个范围内星期一到星期日为 13 号的个数。/*PROG: fridayLANG: C++*/# include <cstdio>const char daytab[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};int isLeap(int year){ return year%4 == 0 && year%100 != 0 || y
阅读全文
摘要:这道题和“扑克牌排序”很相似,但是并不是排成升序,可以用同一种方式对两个序列排序,使第二个为升序,此时第一个序列就成了“扑克牌排序”的情况,只需要统计出第一次逆序出现的位置即可,由于是排列,可以用 O(n) 的方法来做;# include <cstdio># define N 200010int n, a[N], b[N];int p[N];void init(void){ scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int
阅读全文
摘要:a 加 b 的反序表示的数;# include <cstdio># include <cstring>int a, b;char s[11];void init(void){ scanf("%d%s", &a, s);}void solve(void){ b = 0; for (int i = strlen(s)-1; i >= 0; --i) { b *= 10; b += s[i]-'0'; } printf("%d\n", a+b);}int main(){ init(); solve(); r
阅读全文
摘要:简单DP,设 f[i] 为到达第 i 个位置最迟的天数,那么 f[i] 为 min(f[i-2], a[i]) 和 min(f[i-1], a[i]) 中的较大者;# include <cstdio># include <algorithm># define N 1005using namespace std;int n, a[N];int f[N];void init(void){ scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]
阅读全文
摘要:贪心:每次对于比前面的数小的数累加差值即可,比前面大的可以通过加大区间范围保持大小关系不变;# include <cstdio>int n, a[100005];void init(void){ int i; scanf("%d", &n); for (i = 0; i < n; ++i) scanf("%d", &a[i]);}void solve(void){ int i; long long int ans; ans = 0; for (i = 1; i < n; ++i) if (a[i] < a[i
阅读全文
摘要:dp,参考了http://www.cppblog.com/hanfei19910905/archive/2012/06/30/180831.html;定义两组状态 L1[i] 表示在 0-i 内的最大得分,L2[i] 表示从 i 出发回到 i 的最大得分,不难得到状态转移方程,最后枚举 i 组合求出最大值;# include <cstdio># include <algorithm># define N 100005using namespace std;typedef long long int LL;int n, num[N];LL L1[N], L2[N], R1
阅读全文
摘要:简单题,但要仔细分清所有情况,2WA;# include <cstdio>int n, m;void solve(void){ int max, min; if (!n && !m) {printf("0 0\n"); return;} if (n == 0) {puts("Impossible"); return ;} max = m==0 ? n:n+m-1; min = (n>=m ? n:m); printf("%d %d\n", min, max);}int main(){ while (~
阅读全文
摘要:简单题,要注意可能做出0、1、2题,枚举所有情况即可;# include <cstdio>int a, b, x, da, db, t;int i, j;void solve(void){ if (!x || (a>=x && (a-x)%da==0 && (a-x)/da<=t-1) || (b>=x &&(b-x)%db==0&&(b-x)/db<=t-1)) { printf("YES\n"); return ; } for (i = t-1; i >= 0; -
阅读全文
摘要:第一道A的纠结;简单题,WA了几次,最后发现AC的代码 sort 的 cmp 返回的是 bool 型,注意到这点,就 A 了,数据是不会超范围的;# include <cstdio># include <cstring># include <algorithm># define N 100005using namespace std;int n, d, a, b;int c[N], p[N];char f[N];bool cmp(const int &x, const int &y){ return c[x] < c[y];}void
阅读全文
摘要:线段树,离散化;WA了三次,前两次主要是查询时只要遇到标记了颜色就要返回,而不是标记颜色并且没记录过就返回,后一次是空间开的小,因为离散化可能使数据量增加一倍,因此空间至少要开到区间数目的 4 倍;-----------------------------------------------------------2012/4/15View Code # include <cstdio># include <cstring># include <algorithm>using namespace std;# define N 10000 + 5int n,
阅读全文
摘要:字典树,WA;----------------------------------------------------# include <stdio.h># include <string.h># define LEN 12char buf[2 * LEN], str[LEN];struct word{ char a[LEN];} ;struct tree{ tree *node[26]; char bj; word *pw; tree() { for (int i = 0; i < 26; ++i) node[i] = NU...
阅读全文
摘要:线段树,维护区间的和,支持区间范围修改,注意由于增加的标记传递时是累加起来,结果会超出 int ,要用 long long;--------------------------------------------------------------DescriptionYou have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given int
阅读全文
摘要:------------------------------------------------------------------------------------线段树的区间操作:修改区间内的值,反转区间内的值,区间查询;------------------------------------------------------------------------------------Description维护一个只有0和1的整数序列,支持以下操作:1 x y v : 将区间[x,y]之间的所有整数都变为v(v为0或1);2 x y : 将区间[x,y]之间所有的1变为0,所有的0变为
阅读全文
摘要:线段树,维护的是区间内整数的个数,每次插入 x 时,查询在 x 的前面比小的数的个数,并计算出比 x 大的数的个数 cnt[x] ,最后将 cnt 累加,即为逆序数;将队首的数放到队尾后逆序数改变:n-1-a[i], a[i] 为原始序列中第 i 个数的值;----------------------------------------------------------------------2012/7/15之前的代码中,cnt[i] 是记录比第 i 个数大的的在它前面出现的数的个数,第二次写发现不需要。# include <cstdio># include <cstri
阅读全文
摘要:因为输入是按y坐标升序的,对每个点统计在它左边的个数就是它的level(线段树);DescriptionAstronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers
阅读全文
摘要:这道题来自于 The 36th ACM/ICPC Asia Regional Dalian Site —— Online Contest 线段树求第 k 大值,包含修改和询问;----------------------------------------------------------------------------Problem DescriptionXiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write ...
阅读全文
摘要:线段树的做法,1438MS;------------------------------------------------------------------DescriptionFor the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simpl
阅读全文
摘要:线段树,修改,维护区间最大最小、和;Description维护一个整数序列,支持以下操作:1 x v : 将第x个整数的值修改为v;2 x y : 查询区间[x,y]之间的最小值;3 x y : 查询区间[x,y]之间的最大值;4 x y : 查询区间[x,y]内的整数和。Input输入文件包含多组测试数据。对于每组测试数据,第一行为一个整数N(1<=N<=10^5),表示,接下来一行有N个整数,再接下来一行有一个整数M(1<=M<=10^5),表示一共有M个操作。数据保证对于查询操作结果均在int的表示范围内。Output对于每个查询均用一行输出查询的结果。Sampl
阅读全文
摘要:第九届中山大学校赛预选赛(2006)Problem A 信息泛滥大致题意:给出 n 个不同的字符串,再给出 m 个字符串,问这 m 个字符串中在给出的 n 个串中没有出现的个数。思路:建 Trie ,统计即可。----------------------------------------------------------# include <stdio.h>struct tree{ tree *node[26]; int bj; tree() { bj = 0; for (int i = 0; i < 26; ++i) n...
阅读全文
摘要:动态 Trie 会超时,DISCUSS 中有人提醒要用静态数组的 Trie,还没学;这个题要注意除了判断当前串是否有和字典中的串相同的前缀外,还要判断当前串是否是字典中串的前缀;-----------------------------------------------------------------DescriptionGiven a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the ph
阅读全文
摘要:给出的单词不会重复出现,可以建立字典树,设一个域为当前结点重复次数(或者是否重复),对每个单词输出到第一个不重复的字母或者这个单词的结尾。-----------------------------------------------------------------------------------------DescriptionA prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c&
阅读全文
摘要:时限是 3s, 当然不能用 dijksra;N 最大是 20005,数组 d[N][N] 可以开;------------------------------------------------------------------------# include <stdio.h># include <string.h># define N 20005# define M 50005# define INF N*Mint n, m, s, t;int w[N][N];int min(int x, int y){ return (x<y ? x:y);}void in
阅读全文
摘要:迪杰斯特拉算法的过程如下:初始化,把除起点之外的所有点到起点的距离初始化为 INF,起点到起点的距离记为0,标记清空,;FOR i = 1:n 选取到起点距离最近的结点; 如果选取的点为目标点,结束,否则标记这个点,并对它相邻的所有点进行松弛操作;END-----------------------------------------------------------------------------------# include <stdio.h># include <string.h># define N 105# define INF 100005int n,
阅读全文
摘要:Description 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。 移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。 现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。 例如 N=4,4 堆纸牌数分别为: ① 9 ② 8 ③ 17 ④ 6 移动3次可达到目的: 从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9...
阅读全文
摘要:查找第一个串是否是第二个串的子序列;# include <stdio.h># include <string.h># define N 100005char p[N], t[N];char check(char *x, char *y){ int lenx, leny, i, j; lenx = strlen(x), leny = strlen(y); if (lenx > leny) return 0; for (i = 0, j = 0; j < leny; ++j) { if (x[i] == y[j]) ++i; if (i ...
阅读全文
摘要:按照 CSGrandeur 的方法做的;枚举第一个串的所有子串,并查找是否在其他串中出现,需要注意题目要求在最大长度前提下,输出字典序最小的串,这里也点小难,刚开始没看懂大侠的代码,后来试了几种控制方法,有的需要先把 cstr 清空,显得麻烦,才逐渐理解了;# include <stdio.h># include <string.h># define N 65int n;char dic[15][N], cstr[N];char find(void){ char buf[N], ok; int len, i, j; cstr[0] = 0; for (len = 60;
阅读全文
摘要:按照 CSGrandeur 大牛的给出的方法做的;暴力即可;判断是否可以添加一个 字符得到时,有点小技巧,具体见代码;# include <stdio.h># include <string.h># define WL 17int n;char dic[10005][WL], word[WL];char exist(char *buf){ int i; for (i = 0; i < n; ++i) { if (strcmp(dic[i], word) == 0) return 1; } return 0;}char replace(char *x,...
阅读全文
摘要:这道题对枚举时限比较严,在写 check 函数时要注意边界不能超,因为超出边界有可能引用了上一组残留的数据,而使用 memset() 则会超时。# include <stdio.h># define N 1005# define DIR 4 const int dir[][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};int n, m;char b[N][N];char check(int i, int j){ char ch; int cnt, s; for (cnt = 1, s = i-2; s<i+2; ...
阅读全文
摘要:线段树入门题,和敌兵布阵一样只有更新和查询操作,维护的是最大值;# include <stdio.h># include <string.h># define N (1 << 19)# define M (1 << 18)int segMax[N*2+10];int max(int x, int y){ return x>y ? x:y;}void initTree(void){ segMax[0] = 0; memset(segMax, 0, sizeof(segMax));}int update(int p, int val){ p +
阅读全文
摘要:对每个结点 BFS 一遍,找出能被它打败和可以打败它的结点的总和 s ,如果 s == n-1 ,它的排名可以确定;C++ vector 邻接表;# include <cstdio># include <iostream># include <cstring># include <vector># define N 105using namespace std;int n, m;char vis[N];vector <int> pre[N];vector <int> aft[N];int bfs(int u, int d)
阅读全文
摘要:线段树的入门题,数组代替树;线段树是一种完全二叉树,主要操作有建树、修改节点、区间询问(最大值或者和等),由于采用二叉树结构,对一个结点的操作复杂为 logn;这里建树、修改和询问操作没有采用递归方式,主要是利用了线段树也是完全二叉树的特点,因此可以直接根据要查看节点的编号(1..n)求得其对应在树中的编号,就可以直接进行操作,而不需要递归来实现。# include <stdio.h># include <string.h># define N (1 << 17)# define M ((1 << 16) )int segSum[N];void
阅读全文
摘要:Description中南大学ACM的暑期集训马上就要开始了,这次集训会将全体N名集训队员(编号分别为1, 2, …, N)按集训选拔赛的排名分成两组,前K名队员分入A组,其余队员分入B组。但现在助理教练CSGrandeur一不小心把集训选拔赛的排名弄丢了,而之前又没将A组和B组的人员确定出来,于是CSGrandeur打算问一下集训人员他们的名次各是怎样的,以此来确定一下A组的队员。然而集训队员们都视名次如粪土,只是隐约记得某些人排在了自己的后面,最终反馈到CSGrandeur这里的一共有M条信息,每条信息都可以用一个二元组(x, y) (x!=y)表示,含义为第x名队员记得第y名队员的排名比
阅读全文
摘要:(摘自维基百科)卡塔兰数维基百科,自由的百科全书卡塔兰数是组合数学中一个常在各种计数问题中出现的数列。以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名。卡塔兰数的一般项公式为 前几项为 (OEIS中的数列A000108): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640,
阅读全文
摘要:将第 n 个数放在 第 k 个位置上,共 n-1 种;如果第 k 个数放在第 n 个位置,共有 f[n-2] 种,否则由于第 k 个数不能放在第 n 个位置,剩余的数相当于 n-1 个数时的子问题,即f[n-1];# include <stdio.h>long long int f[21], fact[21];void prepare(void){ int i; fact[1] = 1; for (i = 2; i <= 20; ++i) fact[i] = i * fact[i-1]; f[1] = 0; f[2] = 1; ...
阅读全文
摘要:dfs;按照 Staginner 大牛的方法写的,大致思路是:刚开始所有点没有着色,且最终结果至少有一个点被着黑色(一个点时直接着黑色,多个点时,可以任选一个点为黑色,其余点全为白色);枚举这个黑色的点,并且把与它相邻的点都着白色,剩下的可以看作是一个相同的子问题了,因为剩下的点都不与这个黑色的点相邻。最优解满足:每个白色的点至少与一个黑色的点相邻(如果这个点相邻的都是白色,可以把它改为黑色),且每个黑色的点周围都是白色。# include <stdio.h># include <string.h># define N 105int n, m, ans;char g[N
阅读全文
摘要:排序,检索;使用 bsearch 的 cmp 不能只返回 -1 或 1 (可能是要用差进行比较);# include <stdio.h># include <stdlib.h># include <string.h># define N 10005int n, q, a[N], f[N];int cmp(const void *x, const void *y){return ( *(int*)x - *(int*)y );}int main(){ int i, cnt, x; cnt = 0; while (1) { scanf("%d%...
阅读全文
摘要:%*c 用于输入时,忽略一个字符的输入,可用于忽略换行和 getchar() 作用一样;%*c 用于输出时,输出若干个空格后输出一个字符,比如 printf("%*c", 10, 'a'); 是输出9个空格在第十个位置输出'a';题目:打印如下的空心三角形,遇到 '@' 结束 A A A A A A A A A A AAAAAAAAAAAAAA# include <stdio.h>int main(){ int i, n; char ch, ok; ok = 0; while (1) {...
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2093sscanf的使用,字符串对齐,快排;# include <stdio.h># include <stdlib.h># define N 1005typedef struct {char name[15]; int n; int s;} Player;Player p[N];int n, m;int cmp(const void *xx, const void *yy){ Player *x, *y; x = (Player*)xx; y = (Player*)yy; ...
阅读全文
摘要:C++ 中 set 和 map 的使用, 拓扑排序(并查集也能做);Problem Description有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。球赛的规则如下:如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。map 比较好用;# include <iostream># include <set>
阅读全文
摘要:贪心法,看了 DISCUSS 后写的, 以前听过大牛的讲解,这是第一道题。# include <stdio.h># include <stdlib.h># define N 105int n;int t[N][2];int cmp(const void *x, const void *y){ return *(int *)x > *(int *)y ? 1:-1;}int main(){ int i, c, tmp; while (1) { scanf("%d", &n); if (n == 0) break; for ...
阅读全文
摘要:整数坐标下,面积的2倍也是整数;多边形面积公式;# include <stdio.h># define N 105int n;int x[N], y[N];double area(void){ int i; double ret; ret = 0; for (i = 0; i < n-1; ++i) { ret += x[i]*y[i+1] - x[i+1]*y[i]; } ret += x[n-1]*y[0] - x[0]*y[n-1]; return ret*0.5;}int main(){ int i; ...
阅读全文
摘要:马可以从任意位置出发,走遍整个棋盘;先用 bfs 求出马到达每个位置的最短时间 Ti,然后模拟将的移动,当将移动的时间 Tk 满足 Tk>=Ti 且Tk-Ti为偶数时相遇(马可以在两个位置徘徊一会等待将的到来);# include <stdio.h># include <string.h>const int dir[][2] = {{1,2}, {2,1}, {-1,2}, {1,-2}, {-2,1}, {2,-1}, {-1,-2}, {-2,-1}};int nx, ny, kx, ky;char vis[9][8], dis[9][8];void bfs(
阅读全文
摘要:杭电100题,牛们请略过。# include <stdio.h>int cnk[31][31];void prepare(void){ int i, j; for (i = 1; i < 31; ++i) cnk[i][0] = cnk[i][i] = 1; for (i = 2; i < 31; ++i) for (j = 1; j < i; ++j) cnk[i][j] = cnk[i-1][j-1] + cnk[i-1][j];}int main(){ int n, i, j; prepare(); whil...
阅读全文