zoukankan      html  css  js  c++  java
  • $NOIP 2016 Day2$ 模拟考试 题解报告

    (NOIP 2016 Day2) 模拟考试 题解报告

    得分情况

    (T1) (90 Pts)

    (T2 45 Pts) ((Loj) 数据)

    (T2 65 Pts) (洛谷 数据)

    (T3 5 Pts)

    总分: (140/160 Pts)

    考试过程

    (T1) 看一眼 组合数 数论 打表 看到杨辉三角 先写的递推 大概 (70) 然后看到 (k) 直接取模 能过 (90)(95) 一个小时 先扔掉 去看 (T2) 对着数据点一个一个写 写完 (n^2) 的又把 (q = 0) 的单独拿出来 但是还是超时 大概不是很到一个小时 后面的时间死磕 (T3) 但并没有拿多少分

    题解

    (T1) 组合数问题

    (O(n^2)) 预处理 + 二维前缀和优化把查询优化到 (O(1)) 就能过

    代码

    /*
      Time: 6.15
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<cstdio>
    #include<cstring>
    #define int long long
    #define Min(x, y) ((x) < (y) ? (x) : (y))
    /*--------------------------------------头文件*/
    const int A = 1e4 + 7;
    const int B = 1e5 + 7;
    const int D = 1e7 + 7;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    /*------------------------------------常量定义*/
    inline void File() {
    	freopen("problem.in", "r", stdin);
    	freopen("problem.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    int T, k, n, m, f[2021][2021], ans[2021][2021];
    /*------------------------------------变量定义*/
    inline int read() {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    /*----------------------------------------快读*/
    void work() {
    	n = read(); m = read();
    	printf("%lld
    ", ans[n][Min(n, m)]);
    }
    /*----------------------------------------函数*/
    signed main() {
    	File();
    	T = read(); k = read(); f[0][0] = 1;
    	for(int i = 1; i <= 2000; i++)
    	{
    		for(int j = 1; j <= i; j++)
    		{
    			f[i][i - j] = f[i][j] = (f[i - 1][j - 1] + f[i - 1][j]) % k;
    			ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
    			if(!f[i][j]) ans[i][j]++;
    		}
    		ans[i][i + 1] = ans[i][i];
    	}
    	while(T--) work();
    	return 0;
    }
    

    (T2) 蚯蚓

    实际上写了 (70) 分的 复杂度大概是能卡过的 但是似乎由于优先队列的常数过大 后面的六个点就过了一个 吸氧的话分会高一些

    同样没有吸氧的情况下 洛谷数据比 (LOJ) 的数据高 (20) 分 ...

    正解

    题中本身隐含单调性 先被切开的蚯蚓一定比后被切开的蚯蚓长 可以将两堆分别存储 每次切的时候从三堆中取最大的 切完依次放回 时间复杂度 (O(m))

    维护三个队列 第一个表示原蚯蚓 第二个表示切开后较长的蚯蚓 第三个表示切开后较短的蚯蚓

    先将原序列排序 省去每一秒增加每只蚯蚓的长度的操作 转换成在查询砍哪只蚯蚓时 把增加的长度算到蚯蚓的总长度上

    每次在三个队列中找最长的 切开后放到二三里面

    统计答案的时候将三个队列合并 排序输出

    代码

    /*
      Time: 6.15
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define Abs(x) ((x) < 0 ? -(x) : (x))
    #define Max(x, y) ((x) > (y) ? (x) : (y))
    #define Min(x, y) ((x) < (y) ? (x) : (y))
    #define Swap(x, y) ((x) ^= (y) ^= (x) ^= (y))
    /*--------------------------------------头文件*/
    const int B = 1e5 + 7;
    const int C = 8e6 + 7;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    /*------------------------------------常量定义*/
    inline void File() {
    	freopen("earthworm.in", "r", stdin);
    	freopen("earthworm.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    int n, m, q, u, v, t, Q[3][C], l[3], r[3], a[C], cnt;
    /*------------------------------------变量定义*/
    inline int read() {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    /*----------------------------------------快读*/
    bool cmp(int x, int y) {return x > y;}
    void work(int x) {
    	int id, y, z, max = 0;
    	if(l[0] <= r[0] && Q[0][l[0]] + x * q > max) max = Q[0][l[0]] + x * q, id = 0;
    	if(l[1] <= r[1] && Q[1][l[1]] + (x - l[1]) * q > max) max = Q[1][l[1]] + (x - l[1]) * q, id = 1;
    	if(l[2] <= r[2] && Q[2][l[2]] + (x - l[2]) * q > max) max = Q[2][l[2]] + (x - l[2]) * q, id = 2;
    	l[id]++; y = 1ll * max * u / v; z = max - y; if(y < z) Swap(y, z); Q[1][r[1]++] = y; Q[2][r[2]++] = z;
    	if(!((x + 1) % t)) printf("%d ", max);
    }
    void del(int i) {
    	if(i) while(l[i] <= r[i]) a[++cnt] = Q[i][l[i]] + (m - l[i]) * q, l[i]++;
    	else while(l[i] <= r[i]) a[++cnt] = Q[i][l[i]] + m * q, l[i]++;
    }
    /*----------------------------------------函数*/
    int main() {
    	File();
    	n = read(); m = read(); q = read(); u =  read(); v = read(); t = read();
    	l[0] = r[0] = l[1] = r[1] = l[2] = r[2] = 1;
    	for(int i = 1; i <= n; i++) Q[0][i] = read(); r[0] = n;
    	std::sort(Q[0] + 1, Q[0] + 1 + n, cmp);
    	for(int i = 1; i <= m; i++) work(i - 1);
    	for(int i = 0; i <= 2; i++) del(i);
    	std::sort(a + 1, a + 1 + cnt, cmp); puts("");
    	for(int i = t; i <= m + n; i += t) printf("%d ", a[i]);
    	return 0;
    }
    

    (T3) 愤怒的小鸟

    (n^2) 枚举点对 待定系数法直接解方程 把 (x) 相等的判出去 把解出来 (a > 0) 的判出去 对于算出来的每一条抛物线 再枚举每个点 将经过的所有点都压进去 然后 (dp)

    状态: (f_S) 表示经过点集为 (S) 时所用抛物线条数

    转移时外层枚举状态 内层尝试将一个点纳入经过的集合 转移考虑将多少个点同时纳入

    代码:

    /*
      Time: 6.15
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<cstdio>
    #include<cstring>
    #define Abs(x) ((x) < 0 ? -(x) : (x))
    #define Min(x, y) ((x) < (y) ? (x) : (y))
    #define emm(x, a) memset(x, a, sizeof x)
    /*--------------------------------------头文件*/
    const double eps = 1e-9;
    /*------------------------------------常量定义*/
    inline void File() {
    	freopen("angrybirds.in", "r", stdin);
    	freopen("angrybirds.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    int T, n, m, cnt, s[20][20], f[(1 << 18) + 2], ans;
    double x[20], y[20];
    /*------------------------------------变量定义*/
    inline int read() {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    /*----------------------------------------快读*/
    void work() {
    	n = read(); m = read(); emm(f, 63); emm(s, 0); f[0] = 0;
    	for(int i = 1; i <= n; i++) scanf("%lf%lf", x + i, y + i);
    	for(int i = 1; i < n; i++) for(int j = i + 1; j <= n; j++)
    	{
    		if(Abs(x[i] - x[j]) < eps) continue;
    		double a = (y[i] / (x[i] * x[i] - x[i] * x[j]) - y[j] / (x[i] * x[j] - x[j] * x[j]));
    		double b = (y[i] * x[j] * x[j] - y[j] * x[i] * x[i]) / (x[i] * x[j] * x[j] - x[j] * x[i] * x[i]);
    		if(a >= 0 || Abs(a) < eps) continue;
    		for(int k = 1; k <= n; k++) if(Abs(a * x[k] * x[k] + b * x[k] - y[k]) < eps) s[i][j] |= 1 << k - 1;
    	}
    	for(int S = 0; S < 1 << n; S++) for(int i = 1; i <= n; i++) if(!(1 << i - 1 & S))
    	{
    		for(int j = i; j <= n; j++)
    		{
    			if(i == j) f[S | (1 << i - 1)] = Min(f[S | (1 << i - 1)], f[S] + 1);
    			if(Abs(x[i] - x[j]) < eps) continue;
    			f[S | s[i][j]] = Min(f[S | s[i][j]], f[S] + 1);
    		}
    		break;
    	}
    	printf("%d
    ", f[(1 << n) - 1]);
    }
    /*----------------------------------------函数*/
    int main() {
    //	File();
    	T = read(); while(T--) work();
    	return 0;
    }
    
  • 相关阅读:
    五险一金的详细解释
    Android源码下载和编译Tips
    C++ STL遍历map的时候如何删除其中的element
    Android 2.3.4 RTSP的实现不在StageFright中,在opencore中
    找不到显示桌面的快捷方式怎么办|显示桌面的快捷方式找不到解决方法|显示桌面代码|
    选择适合过一辈子的人
    .net兼职人员| .net兼职系统开发人员| .net兼职开发人员
    skype帐号|超值skype帐号|14分钟skype账号|1元40个|5毛20个|15天有效期
    黄金市场的时间段分析
    解决导航问题winform的左侧树控件右侧panel加载用户控件
  • 原文地址:https://www.cnblogs.com/blank-space-/p/14891046.html
Copyright © 2011-2022 走看看