NOIP2013 题解

转圈游戏

  题解:快速幂

 1 #include <cstdio>
 2
 3 int n, m, k, x;
 4
 5 inline long long QuickPow(int a, int k, int MOD){
 6     long long base = a, ret = 1;
 7     while (k){
 8         if (k&1) ret = (ret*base)%MOD;
 9         base = (base*base)%MOD, k >>= 1;
10     }
11     return ret;
12 }
13
14 int main(){
15     scanf("%d %d %d %d", &n, &m, &k, &x);
16     printf("%lld\n", (x%n+(m%n)*QuickPow(10, k, n)%n)%n);
17 }

circle.cpp

火柴排队

  题解:求逆序对(因为写不来归排就写的树状数组,怕TLE就蛋疼的加了一个读入优化)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 const int MAXN =  100000+10;
 7 const int MOD = 99999997;
 8
 9 int n, ans, c[MAXN], d[MAXN];
10 char cc;
11
12 struct Match{
13     int v, n;
14
15     friend bool operator < (const Match& A, const Match& B){
16         return A.v<B.v;
17     }
18 }a[MAXN], b[MAXN];
19
20 inline void add(int p, int v){
21     while (p<=n)
22         d[p] += v, p += (p&(-p));
23 }
24
25 inline int sum(int p){
26     int ret = 0;
27     while (p>0)
28         ret += d[p], p -= (p&(-p));
29     return ret;
30 }
31
32 inline int NextInt(){
33     int ret = 0;
34     do cc = getchar();
35     while (cc<48 || cc>57);
36     do ret *= 10, ret += (cc-48), cc = getchar();
37     while (48<=cc && cc<=57);
38     return ret;
39 }
40
41 int main(){
42     memset(d, 0, sizeof(0));
43     n = NextInt(), ans = 0;
44     for (int i=0; i<n; i++)
45         a[i].v = NextInt(), a[i].n = i+1;
46     sort(a, a+n);
47     for (int i=0; i<n; i++)
48         b[i].v = NextInt(), b[i].n = i+1;
49     sort(b, b+n);
50
51     for (int i=0; i<n; i++)
52         c[a[i].n] = b[i].n;
53
54     for (int i=1; i<=n; i++)
55         add(c[i], 1),
56         ans = (ans+i-sum(c[i]))%MOD;
57     printf("%d\n", ans);
58 }

match.cpp

货车运输

  题解:先建一个最大生成树,再用lca乱搞一下就好了

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5
  6 const int MAXL = 20;
  7 const int MAXN = 10000+10;
  8 const int MAXM = 50000+10;
  9 const int INF = 0x3f3f3f3f;
 10
 11 int n, m, f[MAXN], nimo[MAXN][MAXL], an[MAXN][MAXL], dep[MAXN];
 12 bool vis[MAXN];
 13 char c;
 14
 15 struct Edge{
 16     int d, to;
 17     Edge *next;
 18 }e[MAXM], *head[MAXN];
 19
 20 struct Bary{
 21     int u, v, d;
 22
 23     friend bool operator < (const Bary& A, const Bary& B){
 24         return A.d>B.d;
 25     }
 26 }bd[MAXM];
 27
 28 inline int NextInt(){
 29     int ret = 0;
 30     do c = getchar();
 31     while (c<48 || c>57);
 32     do ret *= 10, ret += (c-48), c = getchar();
 33     while (48<=c && c<=57);
 34     return ret;
 35 }
 36
 37 inline int find(int x){
 38     return x==f[x] ? x : f[x]=find(f[x]);
 39 }
 40
 41 int ne = 0;
 42 inline void AddEdge(int f, int t, int d){
 43     e[ne].to = t, e[ne].d = d;
 44     e[ne].next = head[f];
 45     head[f] = e + ne++;
 46 }
 47
 48 inline void Add(int u, int v, int d){
 49     f[find(u)] = find(v);
 50     AddEdge(u, v, d), AddEdge(v, u, d);
 51 }
 52
 53 inline void BuildTree(int x){
 54     vis[x] = true;
 55     for (Edge *p=head[x]; p; p=p->next)
 56         if (!vis[p->to])
 57             an[p->to][0] = x, nimo[p->to][0] = p->d, dep[p->to] = dep[x]+1, BuildTree(p->to);
 58 }
 59
 60 inline int swim(int &x, int ht){
 61     int ret = INF;
 62     for (int i=MAXL-1; i>=0; i--)
 63         if (dep[an[x][i]]>=ht) ret = min(ret, nimo[x][i]), x = an[x][i];
 64     return ret;
 65 }
 66
 67 inline int lca(int x, int y){
 68     int ret = INF;
 69     if (dep[x]^dep[y]) ret = dep[x]>dep[y] ? swim(x, dep[y]) : swim(y, dep[x]);
 70     if (x==y) return ret;
 71     for (int i=MAXL-1; i>=0; i--)
 72         if (an[x][i]^an[y][i])
 73             ret = min(ret, min(nimo[x][i], nimo[y][i])),
 74             x = an[x][i], y = an[y][i];
 75     return min(ret, min(nimo[x][0], nimo[y][0]));
 76 }
 77
 78 int main(){
 79     memset(vis, false, sizeof(vis));
 80     memset(an, 0, sizeof(an));
 81
 82     n = NextInt(), m = NextInt();
 83     for (int i=1; i<=n; i++)
 84         f[i] = i;
 85     for (int i=0; i<m; i++)
 86         bd[i].v = NextInt(), bd[i].u = NextInt(), bd[i].d = NextInt();
 87
 88     sort(bd, bd+m);
 89     for (int i=0; i<m; i++)
 90         if (find(bd[i].u)^find(bd[i].v)) Add(bd[i].u, bd[i].v, bd[i].d);
 91     for (int i=1; i<=n; i++)
 92         if (!vis[i]) dep[i] = 0, BuildTree(i), nimo[i][0] = INF, an[i][0] = i;
 93
 94     for (int i=1; i<MAXL; i++)
 95         for (int j=1; j<=n; j++)
 96             an[j][i] = an[an[j][i-1]][i-1],
 97             nimo[j][i] = min(nimo[j][i-1], nimo[an[j][i-1]][i-1]);
 98
 99     int Q, a, b;
100     scanf("%d", &Q);
101     while (Q--)
102         scanf("%d %d", &a, &b),
103         printf("%d\n", find(a)==find(b) ? lca(a, b) : -1);
104 }

truck.cpp

机模大赛:

  题解:模拟,ans = ∑max{0, a[i]-a[i-1]}

 1 #include <cstdio>
 2
 3 int num, h[100010];
 4
 5 int max(int a,int b){
 6     return a>b ? a : b;
 7 }
 8
 9 int main(){
10     scanf("%d",&num);
11     for (int i=0; i<num; i++)
12         scanf("%d", &h[i]);
13
14     long long ans = 0;
15     for (int i=0; i<num; i++)
16         ans += max(0, h[i]-h[i-1]);
17     printf("%lld",ans);
18 }

block.cpp

花匠:

  题解:贪心,缩点,把满足的连这的一群点缩为一个

 1 #include <cstdio>
 2 const int MAXN = 1e6+10;
 3
 4 int n, Pri, cj, a[MAXN];
 5
 6 int main(){
 7     scanf("%d", &n), Pri = 1, cj = 1221;
 8     for (int i=0; i<n; i++)
 9         scanf("%d", a+i);
10     for (int i=1; i<n; i++){
11         if (a[i]>a[i-1] && cj!=1) cj = 1, Pri ++;
12         if (a[i]<a[i-1] && cj!=0) cj = 0, Pri ++;
13     }
14     printf("%d", Pri);
15 }

flower.cpp

NOIP2013 题解

时间: 2024-10-31 13:30:00

NOIP2013 题解的相关文章

Noip2013花匠题解

题目描述 Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1,h2,-,hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2,-,gm,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有的1<i<m2,g2i>g2i?1,且g2i>g2i+1: 条件 B:对于所有的1

[部分题解]noip2013提高组Day2

积木大赛: 之前没有仔细地想,然后就直接暴力一点(骗点分),去扫每一高度,连到一起的个数,于是2组超时 先把暴力程序贴上来(可以当对拍机) 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 FILE *fin = fopen("block.in","r"); 5 FILE *fout= fopen("block.out","w&quo

【基础练习】【贪心】【递推】NOIP2013提高组第五题 积木大赛题解

还是先把题目放上吧: 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第n块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成n块高度为 0 的积木).接下来每次操作,小朋友们可以选择一段连续区间[L,R],然后将第L块到第R块之间(含第 L 块和第 R 块)所有积木的高度分别增加1. 小M是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少.但她不是一个勤于动手的孩子,所以想

NOIP2013 花匠 题解(方法全面)

2.花匠 (flower.cpp/c/pas) [问题描述] 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数?1, ?2, - , ?n.设当一部分花被移走后,剩下的花的高度依次为g1,g2,- , gm,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有的1≤i≤,有g2i  >g2i-1,同时对于所有的1≤

NOIP2013 积木大赛 题解(2种解法)

描述 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第 版权声明:本文为博主原创文章,未经博主允许不得转载.

NOIP2013华容道——史上最强题解

[解题思路] 解题思路 这道题的数据范围是n≤30,所以,我们可以看到,裸的O(n4) 的宽搜对于求解q较小的情况是无压力的,但是在q大的情况下,毫无疑问会时间超限,明显,在q较大的情况下,我们需要将每次宽搜中重复搜索的冗余信息除去,所以我们可以先分析题目性质:(这里称要移动的棋子为目标棋子) 首先,如果要移动目标棋子,那么我们首先必须要将空格移到该棋子的上下左右四个方 向上相邻位置之一,然后才可以移动该棋子. 然后,我们分析该棋子移动时候的性质: 棋子每次可以移动,仅当空格位于其相邻位置的时候

【NOIP2013】火柴排队

P1092 - [NOIP2013]火柴排队 Description Input 共三行,第一行包含一个整数 n,表示每盒中火柴的数目. 第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度. 第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度. Output 输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果. Sample Input 样例1: 4 2 3 1 4 3 2 1 4 样例2: 4 1 3 4 2 1 7 2

[题解+总结]20151015分治

1.前言 互测题第四弹——来自Cab的分治(也就意味着昨天就是我的了).感觉今天的题目质量很高的,涉及的知识很全面,虽然都是在分治的基础上.暴力全部没有打对,唉. 2.Color 栅栏涂漆 大概题意:给出n个高度为h[i]的栅栏,每次可以横着或竖着给一行或一列涂色,每个栅栏小格子只能被涂色一次,求最少要涂色多少次. 题解:二分.和NOIP2013的积木大赛非常相似,但是本题可以一列一列涂色,但是可以注意到,我们当且仅当目前处理的区域只存在一列时才需要一列涂色,所以差别并不大. 3.chebnea

[题解+总结]动态规划大合集II

1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2.lis 最长上升子序列 唯一一道裸题,但是O(n^2)过不了,临时看了看O(n log n)的二分做法和线段树做法.先来讲讲简单的二分做法,其本质就是在O(n^2)上进行优化,需要证明一个结论.设当前处理数列第k位,存在: (1)a[i]<a[j]<a[k]: (2)i<j<k: (3