NOIP2014解题报告
day 1
1.生活大爆炸版石头剪刀布(rps)
直接按照题意模拟即可
#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std; const int maxn = 209;
const int Mark[5][5] = {{0, 0, 1, 1, 0}, {1, 0, 0, 1, 0}, {0, 1, 0, 0, 1}, {0, 0, 1, 0, 1}, {1, 1, 0, 0, 0}}; int N, Na, Nb;
int a[maxn], b[maxn]; int main() { scanf("%d%d%d", &N, &Na, &Nb);
for(int i = 0; i < Na; i++) scanf("%d", a + i);
for(int i = 0; i < Nb; i++) scanf("%d", b + i); int ansa = 0, ansb = 0, pa = 0, pb = 0;
while(N--) {
ansa += Mark[a[pa]][b[pb]];
ansb += Mark[b[pb]][a[pa]];
if((++pa) >= Na) pa -= Na;
if((++pb) >= Nb) pb -= Nb;
}
printf("%d %d\n", ansa, ansb); return 0;
}
2.联合权值(link)
比较基础的树形dp. mxx,cntx表示以x为根的子树中结点x的孩子的最大权值和总权值, 在对树进行dfs时计算出结果.
时间复杂度O(N)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype> using namespace std; const int maxn = 200009;
const int MOD = 10007; int N, w[maxn], mx[maxn], cnt[maxn], ans = 0, tot = 0; inline int read() {
char c = getchar();
int ret = 0;
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar())
ret = ret * 10 + c - '0';
return ret;
} struct edge {
int to;
edge* next;
} E[maxn << 1], *pt = E, *head[maxn]; inline void add(int u, int v) {
pt->to = v; pt->next = head[u]; head[u] = pt++;
}
inline void addedge(int u, int v) {
add(u, v); add(v, u);
} void init() {
scanf("%d", &N);
for(int i = 1; i < N; i++) {
int u = read() - 1, v = read() - 1;
addedge(u, v);
}
for(int i = 0; i < N; i++) scanf("%d", w + i);
} void dfs(int x, int fa = -1) {
mx[x] = cnt[x] = 0;
for(edge* e = head[x]; e; e = e->next) if(e->to != fa) {
dfs(e->to, x);
ans = max(ans, w[x] * mx[e->to]);
ans = max(ans, w[e->to] * mx[x]);
tot = (tot + w[x] * cnt[e->to] + w[e->to] * cnt[x]) % MOD;
(cnt[x] += w[e->to]) %= MOD;
mx[x] = max(mx[x], w[e->to]);
}
} int main() { init();
dfs(0);
printf("%d %d\n", ans, tot * 2 % MOD); return 0;
}
3.飞扬的小鸟(bird)
完全背包, dp(x, y)表示小鸟在坐标(x, y)处的最小点击屏幕数.
从左到右dp, 状态转移方程为 dp(x, y) = min{dp(x-1,y-INCx-1)+1,dp(x,y-INCx-1)+1,dp(x,y+DECx-1)}
其中INCx表示横坐标为x点击一次屏幕的上升高度.
我们知道完全背包是要顺序枚举, 这道题也是, y要从1开始枚举. 还要注意先算点击屏幕的, 再算不点击屏幕让bird自己下来的, 这样才不会重复. 不能到达终点就在dp过程中算一算.
时间复杂度O(NM)
#include<cstring>
#include<algorithm>
#include<cstdio> using namespace std; const int maxn = 10009;
const int inf = 0x3f3f3f3f; int N, V, n;
int Inc[maxn], Dec[maxn], L[maxn], R[maxn], dp[2][maxn]; void init() {
scanf("%d%d%d", &N, &V, &n);
for(int i = 0; i < N; i++)
scanf("%d%d", Inc + i, Dec + i);
for(int i = 1; i <= N; i++) L[i] = 0, R[i] = V + 1;
while(n--) {
int p; scanf("%d", &p);
scanf("%d%d", L + p, R + p);
}
} int main() { init();
int c = 0, p = 1, cnt = 0;
memset(dp, inf, sizeof dp);
for(int i = 1; i <= V; i++) dp[c][i] = 0;
for(int i = 1; i <= N; i++) {
swap(c, p);
memset(dp[c], inf, sizeof dp[c]);
for(int j = 1; j <= V; j++)if(j - Inc[i - 1] > 0)
dp[c][j] = min(dp[c][j], min(dp[c][j - Inc[i - 1]], dp[p][j - Inc[i - 1]]) + 1);
for(int j = V - Inc[i - 1]; j <= V; j++)
dp[c][V] = min(dp[c][V], min(dp[p][j], dp[c][j]) + 1);
for(int j = 1; j <= V; j++) if(j + Dec[i - 1] <= V)
dp[c][j] = min(dp[c][j], dp[p][j + Dec[i - 1]]);
for(int j = 1; j <= L[i]; j++) dp[c][j] = inf;
for(int j = R[i]; j <= V; j++) dp[c][j] = inf;
bool F = false;
for(int j = L[i]; ++j < R[i]; )
F |= dp[c][j] < inf;
if(!F) {
printf("0\n%d\n", cnt);
return 0;
}
if(R[i] <= V) cnt++;
}
int ans = inf;
for(int i = L[N]; ++i < R[N]; ) ans = min(ans, dp[c][i]);
printf("1\n%d\n", ans); return 0;
}
day1的题目总体上比较简单, 或者说有点过于简单了.
day 2
1.无限网路发射器选址(wrieless)
直接枚举每一个点, 再对于每一个点暴力算即可.
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int maxn = 139; int w[maxn][maxn]; int main() { memset(w, 0, sizeof w);
int d, n;
scanf("%d%d", &d, &n);
while(n--) {
int x, y; scanf("%d%d", &x, &y);
scanf("%d", w[x] + y);
}
int tot, ans = 0;
for(int i = 0; i < 129; i++)
for(int j = 0; j < 129; j++) {
int cnt = 0;
for(int a = max(0, i - d); a <= min(128, i + d); a++)
for(int b = max(0, j - d); b <= min(128, j + d); b++)
cnt += w[a][b];
if(cnt > ans)
tot = 1, ans = cnt;
else if(cnt == ans)
tot++;
}
printf("%d %d\n", tot, ans); return 0;
}
2.寻找道路(road)
先从终点反向dfs一遍标出T能到达的点, 然后对于每个点检查它的出边是否被标记来确定是否可经过此点. 然后跑最短路即可.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue> using namespace std; const int maxn = 10009;
const int inf = 0x3f3f3f3f; struct edge {
int to;
edge* next;
} E[400009], *pt = E, *head[maxn]; void addedge(int u, int v) {
pt->to = v; pt->next = head[u]; head[u] = pt++;
} int N, S, T, d[maxn];
bool vis[maxn], ok[maxn], inq[maxn];
queue<int> q; int sp() {
if(!ok[S]) return -1;
memset(d, inf, sizeof d);
memset(inq, 0, sizeof inq);
d[S] = 0; q.push(S); inq[S] = true;
while(!q.empty()) {
int x = q.front(); q.pop();
for(edge* e = head[x]; e; e = e->next) if(ok[e->to] && d[e->to] > d[x] + 1) {
d[e->to] = d[x] + 1;
if(!inq[e->to])
q.push(e->to), inq[e->to] = true;
}
}
return d[T] != inf ? d[T] : -1;
} namespace G { edge* head[maxn]; void addedge(int u, int v) {
pt->to = v; pt->next = head[u]; head[u] = pt++;
} void dfs(int x) {
if(vis[x]) return;
vis[x] = true;
for(edge* e = head[x]; e; e = e->next) dfs(e->to);
}
} int main() { memset(vis, 0, sizeof vis);
int m;
scanf("%d%d", &N, &m);
while(m--) {
int x, y; scanf("%d%d", &x, &y); x--; y--;
if(x == y) continue;
addedge(x, y);
G::addedge(y, x);
}
scanf("%d%d", &S, &T); S--; T--;
G::dfs(T);
for(int i = 0; i < N; i++) {
ok[i] = true;
if(!vis[i]) {
ok[i] = false;
continue;
}
for(edge* e = head[i]; e; e = e->next)
if(!vis[e->to]) ok[i] = false;
}
printf("%d\n", sp()); return 0;
}
3.解方程(equation)
当f(x) = 0时, f(x) mod p = 0. 那么当f(x) mod p = 0时f(x)就有可能=0.
我们可以取几个质数, 然后对于[1,m]每一个都进行验证. 只需算出x在[1,p)中的结果即可, x在[p,m]上, f(x) mod p = f(x%p) mod p.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype> using namespace std; const int p[] = {20011, 20021, 20023, 20029, 20047};
const int maxn = 209;
const int pn = 5; int a[pn][maxn], f[pn][23000], N, M;
int ans[1000009], n = 0; void Read(int x) {
bool F = true;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') F = false;
int ret[pn];
for(int i = 0; i < pn; i++) ret[i] = 0;
for(; isdigit(c); c = getchar())
for(int i = 0; i < pn; i++)
ret[i] = (ret[i] * 10 + c - '0') % p[i];
for(int i = 0; i < pn; i++)
a[i][x] = F ? ret[i] : p[i] - ret[i];
} int calculate(int x, int y) {
int ret = 0;
for(int i = N; i; i--)
ret = (ret + a[x][i]) * y % p[x];
if((ret += a[x][0]) >= p[x]) ret -= p[x];
return ret;
} int main() { scanf("%d%d", &N, &M);
for(int i = 0; i <= N; i++) Read(i);
for(int i = 0; i < pn; i++)
for(int j = 0; j < p[i]; j++)
f[i][j] = calculate(i, j);
for(int i = 1; i <= M; i++) {
bool t = true;
for(int j = 0; j < pn; j++)
if(f[j][i % p[j]]) t = false;
if(t) ans[n++] = i;
}
printf("%d\n", n);
for(int i = 0; i < n; i++) printf("%d\n", ans[i]); return 0;
}
day2前2题依旧是简单, 第三题比较有难度
NOIP2014解题报告的更多相关文章
- NOIp2014 解题报告
有史以来第一届面向社会征题的NOIp结束了.最开始以为面向社会征题会很难,但是这是我参加的最水的一次NOIp了. 由于停了两月的课,所以现在正在补文化科目就没时间打代码了.所以所有的题目就均不给出代码 ...
- NOIP2014 解题报告·水渣记
Day 1: 第一次参加noip.小激动,小紧张,这些正常的情绪就不用说了.唯一值得一提的是 我早上步行去郑大工学院的时候迷路了,直接转进了隔壁的河南农大,绕了半天找不到机房,还给几个同学打了电话可就 ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
随机推荐
- hdu 4545 魔法串 2013金山西山居创意游戏程序挑战赛——初赛(1)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4545 这题太坑了,小明的串可以任意删掉某个字符 这句话不知道大家是怎么理解的,我觉得应该是能够删除其中 ...
- 批处理[Batch]
批处理 1. 定义:就是一堆DOS命令按一定顺序排列而形成的集合. 英文译为BATCH,批处理文件后缀BAT就取的前三个字母. 示例1:a.bat @echo off Netstat –a –n &g ...
- When Is Cheryl's Birthday
大早上起来逛微博,看见@西瓜大丸子汤Po的一个逻辑题,遂点开看之... 原文链接:http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.i ...
- ubuntu openstack
https://wiki.ubuntu.com/ServerTeam/CloudArchive/ sudo add-apt-repository cloud-archive:junoLong Term ...
- STC15?MSP430?ARM?DSP?
自从大学毕业以来,发现属于自己的时间越来越少,每天忙于工作,导致在大学学到的东西都好生疏,特别是大一刚开始学的模电,单片机等,现在才慢慢的抓起来,然后在这个多核处理器流行的时代,单片机貌似快过时了,但 ...
- hbase0.96 put流程 源码分析
无意间多瞄了一眼hbase0.98的代码,想复习下put流程.发现htable里面已经找不到processBatchOfPuts()奇怪了.看了半天原来变化还真大事实上0.96就没这个了,于是又搞了个 ...
- Android消息机制之Handler
Android为什么要提供Handler Android建议我们不要在UI线程中执行耗时操作,因为这很容易导致ANR异常(在Android源码中我们可以看到,UI如果对用户的操作超过5秒无响应,就会报 ...
- connot find one or more components. please reinstall the application
正在用 Visual Studio 2013 写程序,程序一直执行正常. 此时,手动把注册表"HKEY_USERS"的当前用户的权限删除.再运行程序会提示:“是否继续并运行上次的成 ...
- Java调用R——rJava的安装和配置
rJava是Java通过JRI调用R所要安装的包.配置起来比较麻烦,我参考网上进行配置,使用rJava包中example里面的示例测试,控制台显示: Cannot find JRI native li ...
- JZOI
orz..kpm大神做的JZOI卡.很好看 目前是全球限量十张哈哈哈 (正面) (背面) 原图: