Codeforces Round #321 div2
好像前几场的题解忘记写了, Orz 状态太差, 平均出两题 都不好意思写了 , 连掉4场, 都要哭晕了。
很水的一场, 写完A B C就去睡了 D题其实不难, E题研究Ing(已用一种奇怪的姿势AC了)
Problem_A:
题意:
给一个长度为n的序列, 找出最长不下降子序列。
思路:
线性扫一遍, 每读入一个数就判断下是否和前面的组成不下降子序列, 维护最大答案和当前序列长度即可(注意处理最后一个序列即可)。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 100010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
int n;
int f[MAXN]; int main()
{
int ans_i = ;
int max_num = ;
scanf("%d", &n);
for(int i = ; i < n; i ++)
{
scanf("%d", &f[i]);
if(i == ) continue;
if(f[i] < f[i - ])
{
max_num = max(max_num, (i - - ans_i + ));
ans_i = i;
}
}
if(ans_i != n - )
{
max_num = max(max_num, (n - - ans_i + ));
}
if(n == ) max_num = ;
printf("%d\n", max_num);
return ;
}
Problem_B:
题意:
你想邀请朋友来参加聚会, 每个朋友都有一个财富值和亲密度, 当你邀请的朋友中存在两个人财富值之差大于等于d, 那么就有有个朋友感到自己比较穷,但是你并不像让这种情况发生。
求使得邀请过来的朋友满足上诉要求,并求最大的亲密度和。
思路:
首先邀请朋友的第一要素是财富值, 所以先按财富值排序, 细想一下, 这个题和A题很像。这里就是找到所有满足要求的区间,然后比较得到最大财富值。
线性扫一遍, 维护区间起点即可。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 100010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
struct node
{
int m;
int s;
};
int n, d;
struct node f[MAXN];
bool cmp(struct node x, struct node y)
{
return x.m < y.m;
} int main()
{
LL pre_id = ;
LL ans = ;
LL temp = ;
scanf("%d %d", &n, &d);
for(int i = ; i <= n; i ++)
scanf("%d %d", &f[i].m, &f[i].s);
sort(f + , f + n + , cmp);
for(int i = ; i <= n; i ++)
{
if(f[i].m - f[pre_id].m < d)
{
temp += f[i].s;
}
else
{
ans = max(ans, temp);
while(f[i].m - f[pre_id].m >= d)
{
temp -= f[pre_id].s;
pre_id ++;
}
temp += f[i].s;
}
}
ans = max(ans, temp);
printf("%I64d\n", ans);
return ;
}
Problem_C:
题意:
给一棵树, 根节点是你的家, 叶子节点是饭馆,每个节点可能存在猫, 你想去饭馆吃饭, 但是又怕猫。如果存在一条路径, 路径上连续的猫的个数 > m个,那么你就可以不能去那个饭馆, 因为你怕猫。
求你能到达的饭馆个数。
思路:
搜索, dfs, 搜索出所有路径, 然后判断路径是否满足要求,搜索下一个状态时需要当前状态, 因为要判断是否是连续的。建边双向建, 叶子节点即所有边都被访问过。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 100010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
int n, m;
int ans = ;
vector <int> edge[MAXN];
int num[MAXN];
bool vis[MAXN];
void init()
{
memset(vis, false, sizeof(vis));
for(int i = ; i < MAXN; i ++)
edge[i].clear();
int ans = ;
}
bool is_ok(int u)
{
for(int i = ; i < edge[u].size(); i ++)
if(!vis[edge[u][i]]) return false;
return true;
}
void dfs(int root, int cat_num)
{
vis[root] = true;
if(cat_num > m) return ;
if(is_ok(root))
{
ans ++;
return ;
}
for(int i = ; i < edge[root].size(); i ++)
{
int v = edge[root][i];
if(!vis[v])
{
if(num[v])
dfs(v, cat_num + num[v]);
else
dfs(v, );
}
}
} int main()
{
init();
scanf("%d %d", &n, &m);
for(int i = ; i <= n; i ++)
scanf("%d", &num[i]);
int x, y;
for(int i = ; i < n - ; i ++)
{
scanf("%d %d", &x, &y);
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs(, num[]);
printf("%d\n", ans);
return ;
}
Problem_D:
题意:
去饭馆吃饭(又吃饭, 囧),菜单上有n道菜, 你想吃m道菜, 且每道最多吃一次, 每一道菜有一个欢乐度, 如果你吃了x 后 又吃y 那么你将得到 c的欢乐度。
求问你能获得的最大欢乐度。
思路:
最多只有18道菜, 答案又是求最优解, 第一反应就是状压。
因为x y 要按顺序, 连续吃下去才能得到c的欢乐度, 所以需要记录一下最后吃的是什么。
那么状态设为:dp[staues][last], staues为二进制集合, last为当前状态最后吃的那道菜,
so,转移方程就出来了, 因为每道菜要么吃, 要么不吃, 就成了个状压的01背包问题了。
dp[staues | (1 << i)][i] = max(dp[staues |(1 << i)][i], dp[staues][last] + a[i] + ruler[last][i]), 初始化时注意下初始为-1, 因为有可能出现0的情况(全部的a[i] = 0)
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 19
#define MAXM (1 << 19)
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
LL dp[MAXM][MAXN];
LL ruler[MAXN][MAXN];
LL a[MAXN];
int n, m, k;
void read()
{
int x, y;
LL c;
memset(ruler, , sizeof(ruler));
scanf("%d %d %d", &n, &m, &k);
for(int i = ; i < n; i ++)
scanf("%lld", &a[i]);
for(int i = ; i < k; i ++)
{
scanf("%d %d %lld", &x, &y, &c);
-- x;
-- y;
ruler[x][y] = c;
}
}
bool is_ok(int x)
{
int num = ;
while(x)
{
if(x & ) num ++;
x /= ;
}
return num == m;
}
LL solve()
{
memset(dp, -, sizeof(dp));
LL ans = ;
for(int staues = ; staues < ( << n); staues ++)
{
for(int last = ; last < n; last ++)
{
int u = << last;
if(staues == )
{
dp[staues | u][last] = a[last];
}
else if(dp[staues][last] != -)
{
for(int cas = ; cas < n; cas ++)
{
int v = << cas;
if(staues & v) continue;
dp[staues | v][cas] = max(dp[staues | v][cas], dp[staues][last] + a[cas] + ruler[last][cas]);
}
}
if(is_ok(staues)) ans = max(ans, dp[staues][last]);
}
}
return ans;
} int main()
{
read();
printf("%lld\n", solve());
return ;
}
Problem_E:
题意;
给一个长度为n的字符串, 这个字符串由0~9组成, 现在有2种操作:
1:l, r, c, 将[l, r]这段区间上的数字全变成c。
2:l, r, d, 判断以l , r开头, 长度为d的两个字符串是否相等。
对每个第二种操作, 输出结果。
思路:
这道题正解应该是线段树 + hash的, 将数字进行hash, 然后第一个操作就是线段树中的区间修改, 第二个操作就是查询是否想等。
然而, 这道题还有一个神奇的解法:仅用两个系统函数 + 一个if 就解出来了。
memset(), memcmp()
用memset将l, r 进行覆盖, 用memcmp进行判断。
这里给出第二种解法, Orz 其实第一种我还不会。
代码:
#include <stdio.h>
#include <string.h>
#define MAXN 100010
int n, m, k;
char s[MAXN]; int main()
{
int op, l, r, val; memset(s, '\0', sizeof(s)); scanf("%d %d %d", &n, &m, &k);
scanf("%s", s); for (int i = ; i < m + k; ++ i)
{
scanf("%d %d %d %d", &op, &l, &r, &val);
-- l;
-- r;
if(op == )
memset(s + l, val + '', r - l + );
else
printf(!memcmp(s + l, s + l + val, r - l + - val)? "YES\n" : "NO\n");
}
return ;
}
Codeforces Round #321 div2的更多相关文章
- Codeforces Round #539 div2
Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...
- 【前行】◇第3站◇ Codeforces Round #512 Div2
[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...
- Codeforces Round#320 Div2 解题报告
Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...
- Codeforces Round #564(div2)
Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...
- Codeforces Round #361 div2
ProblemA(Codeforces Round 689A): 题意: 给一个手势, 问这个手势是否是唯一. 思路: 暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可. 代码: #incl ...
- Codeforces Round #626 Div2 D,E
比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...
- CodeForces Round 192 Div2
This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...
- Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash
E. Kefa and Watch Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/prob ...
- Codeforces Round #321 (Div. 2) C. Kefa and Park dfs
C. Kefa and Park Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/probl ...
随机推荐
- Error: no `server' JVM at...解决办法 【转】
出现问题:用java -jar XXX.jar -server -Xms900m -Xmx900m 提示错误Error: no `server' JVM at `C:\Program Files\Ja ...
- oracle pde文件导入
pde使用pl/sql developer的tools->import tables->pl/sql developer来导入
- 关于Servlet中重定向
public class Red1Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpSer ...
- 玩转Android之二维码生成与识别
二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了.那么今天我们就来看看怎么样在我们自己的App中集成二维码的 ...
- PHP第四章数组2
$str =array("dd"=>"d","dc"=>"ds","dd"=>&q ...
- Manually connecting to the Oracle Linux Yum Server
Manually connecting to the Oracle Linux Yum Server 1. Download and Install Oracle Linux Note: The ...
- E: Sub-process /usr/bin/dpkg returned an error code (1)
E: Sub-process /usr/bin/dpkg returned an error code (1) 错误描述 dpkg: error processing archive /var/cac ...
- nyoj 32 组合数
组合数 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 找出从自然数1.2.... .n(0<n<10)中任取r(0<r< ...
- day0
/* 考前最后一天了 由于下午赶路 就放到上午发了 早晨浏览博客 上午浏览博客 感谢学弟为我写的博客233 很开心认识你们这一群人 嗯 最后一天了 就要说再见了 大家加油吧 ^ ^ */
- C# 右键菜单 contextMenuStrip
1.添加contextMenuStrip控件 默认命名:contextMenuStrip1 2.在要显示的控件上,找到其ContextMenuStrip属性,并设置其为contextMenuStrip ...