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

    (NOIP 2017 Day1) 模拟考试 题解报告

    得分情况

    (T1) (100 Pts)

    (T2) (100 Pts)

    (T3) (10 Pts)

    总分: (210 Pts)

    考试过程

    (T1) 背结论

    (T2) 一开始半个小时比较乱 去看了一下 (T3) 捣鼓半个小时 感觉是 (dp) 但是没什么思路 又回过头来看 (T2) 理清思路 写了半个小时 又造样例自测 感觉没问题去写 (T3) 发现只会 (k = 0) 的情况 写了个比较傻的 (dp) 然后想别的 不会写 所以写了个暴力 又怕 (dp) 错 分了一下测试点 然后 (dp) 的那一部分过了 暴力的挂了...

    题解

    (T1) 小凯的疑惑

    [ans = x imes y - x - y ]

    /*
      Time: 6.6
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<cstdio>
    #define int long long
    /*--------------------------------------头文件*/
    inline void File() {
    	freopen("math.in", "r", stdin);
    	freopen("math.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    
    /*------------------------------------变量定义*/
    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;
    }
    /*----------------------------------------快读*/
    
    /*----------------------------------------函数*/
    signed main() {
    	File(); 
    	int x = read(), y = read();
    	printf("%lld", x * y - x - y);
    	return 0;
    }
    
    

    (T2) 时间复杂度

    大模拟 没什么好说的

    /*
      Time: 6.6
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    /*--------------------------------------头文件*/
    const int A = 1e4 + 7;
    const int B = 1e5 + 7;
    const int C = 1e6 + 7;
    const int D = 1e7 + 7;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    /*------------------------------------常量定义*/
    inline void File() {
    	freopen("complexity.in", "r", stdin);
    	freopen("complexity.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    int T, n, st[A], cnt, cnt1, cnt2, O, t, z[110];
    std::map <std::string, bool> vis;
    std::string s, op, s1, s2, s3, pos[110];
    bool ERR, NO, YES, p;
    /*------------------------------------变量定义*/
    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 work1(int i) {//cnt2 无效循环 cnt1 有效循环 
    	std::cin >> s1 >> s2 >> s3; pos[i] = s1;
    	if(vis[s1]) {ERR = 1; return ;} vis[s1] = 1;
    	if(cnt2) st[++cnt] = i, cnt2++;
    	else if(s3[0] == 'n')
    	{
    		if(s2 < s3) O++, z[++cnt1] = 2, p = 1;//O(n)
    		else z[++cnt1] = 1;
    		if(O == t) YES = 1;
    		if(O > t) NO = 1;
    		st[++cnt] = i;
    	}
    	else if(s2[0] == 'n')
    	{
    		if(s1[0] != 'n') cnt2++, st[++cnt] = i;
    	}
    	else
    	{
    		int a = 0, b = 0;
    		for(int j = 0; j < s2.length(); j++) a = a * 10 + s2[j] - 48;
    		for(int j = 0; j < s3.length(); j++) b = b * 10 + s3[j] - 48;
    		if(a <= b) z[++cnt1] = 1; else cnt2++; st[++cnt] = i;
    	}
    }
    void work2() {
    	if(cnt2) {vis[pos[st[cnt--]]] = 0; cnt2--; return ;}
    	if(!cnt) {ERR = 1; return ;}
    	vis[pos[st[cnt--]]] = 0; if(z[cnt1--] == 2) O--;
    }
    void clear() {
    	cnt1 = cnt2 = ERR = NO = YES = O = t = p = 0;
    	for(int i = 1; i <= n; i++) vis[pos[i]] = 0, pos[i].clear();
    }
    void work() {
    	clear();
    	n = read(); std::cin >> s; if(n & 1) ERR = 1;
    	if(s[2] == '1') t = 0;
    	else for(int j = 4; j < s.length() - 1; j++) t = t * 10 + s[j] - 48;
    	for(int i = 1; i <= n; i++)
    	{
    		std::cin >> op;
    		if(op[0] == 'F') work1(i);
    		else work2();
    	}
    	if(!p && !t) YES = 1;
    	if(cnt1 || cnt2 || ERR) puts("ERR");
    	else if(NO) puts("No");
    	else if(!YES) puts("No");
    	else puts("Yes");
    }
    /*----------------------------------------函数*/
    int main() {
    	File();
    	T = read(); while(T--) work();
    	return 0;
    }
    /*
    五点 无进展 
    最后写 
    8
    2 O(1)
    F i 1 1
    E
    2 O(n^1)
    F x 1 n
    E
    1 O(1)
    F x 1 n
    4 O(n^2)
    F x 5 n
    F y 10 n
    E
    E
    4 O(n^2)
    F x 9 n
    E
    F y 2 n
    E
    4 O(n^1)
    F x 9 n
    F y n 4
    E
    E
    4 O(1)
    F y n 4
    F x 9 n
    E
    E
    4 O(n^2)
    F x 1 n
    F x 1 10
    E
    E
    
    样例过了 跑路了 
    */
    

    (T3) 逛公园

    首先题目给人一种 (dp) 的感觉 然后看到 (K) 的范围 必然是一个和 (K) 有关的 (dp)

    状态 设 (f_{u, x}) 表示 到达 (u) 点时距 (n) 点距离为 (x) 的路径条数

    (dis_u) 表示 (1) 号点到 (u) 点的最短路 (w_{u, v}) 表示两点之间的边权

    转移 (f_{u, x} = sum f_{v, x + dis_u - dis_v - w_{u, v}})

    (y = x + dis_u - dis_v - w_{u, v}) 在转移过程中 (y < 0)(y > x) 一定是不合法的(考虑状态就可以知道) 再考虑 (-1) 的情况 容易发现 当路径有无数条时候 一个状态一定会被多次经过 也就是第二次到达 (u) 点的时候 (u) 点的 (x) 值没有发生改变 那么必然有一种方式再次回到 (u) 点使得 (x) 值仍不变(其实就是 (0) 环) 记录重复即可

    初始状态 (f_{n, x})(x) 需要枚举

    代码

    /*
      Time: 6.6
      Worker: Blank_space
      Source:
    */
    /*--------------------------------------------*/
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define p1 first
    #define p2 second
    #define mk std::make_pair
    /*--------------------------------------头文件*/
    const int A = 2e3 + 7;
    const int B = 1e5 + 7;
    const int INF = 0x3f3f3f3f;
    /*------------------------------------常量定义*/
    inline void File() {
    	freopen("park.in", "r", stdin);
    	freopen("park.out", "w", stdout);
    }
    /*----------------------------------------文件*/
    int T, n, m, k, mod, dis[B], vis[B][60], f[B][60], ans;
    struct edge {int v, w, nxt;} e[B << 1], g[B << 1];
    int head[B], ecnt, ghead[B], gcnt;
    std::priority_queue <std::pair <int, int> > q;
    bool flag, _d[B];
    /*------------------------------------变量定义*/
    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 add_edge(int u, int v, int w) {
    	e[++ecnt] = (edge){v, w, head[u]}; head[u] = ecnt;
    	g[++gcnt] = (edge){u, w, ghead[v]}; ghead[v] = gcnt;
    }
    void dijk() {
    	memset(dis, 63, sizeof dis);
    	dis[1] = 0; q.push(mk(-dis[1], 1));
    	memset(_d, 0, sizeof _d);
    	while(!q.empty())
    	{
    		int u = q.top().p2; q.pop(); if(_d[u]) continue; _d[u] = 1;
    		for(int i = head[u]; i; i = e[i].nxt)
    		{
    			int v = e[i].v, w = e[i].w;
    			if(dis[v] > dis[u] + w) dis[v] = dis[u] + w, q.push(mk(-dis[v], v));
    		}
    	}
    }
    void dfs(int u, int x) {
    	if(vis[u][x] == 1 || flag) {flag = 1; return ;}
    	if(vis[u][x] == 2) return ; vis[u][x] = 1;
    	for(int i = ghead[u]; i; i = g[i].nxt)
    	{
    		int v = g[i].v, w = g[i].w, y = x + dis[u] - dis[v] - w;
    		if(y < 0 || y > x) continue; dfs(v, y);
    		f[u][x] = (f[u][x] + f[v][y]) % mod;
    	}
    	vis[u][x] = 2;
    }
    void work() {
    	n = read(); m = read(); k = read(); mod = read(); ans = 0; flag = 0;
    	memset(head, 0, sizeof head); ecnt = 0; memset(ghead, 0, sizeof ghead); gcnt = 0;
    	memset(f, 0, sizeof f); f[1][0] = 1; memset(vis, 0, sizeof vis);
    	for(int i = 1; i <= m; i++)
    	{
    		int x = read(), y = read(), z = read();
    		add_edge(x, y, z);
    	}
    	dijk();
    	for(int i = 0; i <= k; i++)
    	{
    		dfs(n, i); ans = (ans + f[n][i]) % mod;
    		if(flag) {ans = -1; break;}
    	}
    	printf("%d
    ", ans);
    }
    /*----------------------------------------函数*/
    int main() {
    //	File();
    	T = read(); while(T--) work();
    	return 0;
    }
    /* 
    先跑最短路 
    求长度不超过 d + k 的路径条数 
    无穷多的路径一定存在 0 环 
    2
    5 7 2 10
    1 2 1
    2 4 0
    4 5 2
    2 3 2
    3 4 1
    3 5 2
    1 5 3
    2 2 0 10
    1 2 0
    2 1 0
    
    3
    5 10 0 100000
    1 2 1
    2 3 3
    3 4 4
    4 2 1
    4 5 2
    3 6 2
    6 5 4
    1 4 8
    1 5 10
    2 6 5
    5 8 0 100000
    1 2 1
    2 4 0
    4 5 2
    2 3 2
    3 4 1
    3 5 2
    1 5 3
    1 4 1
    9 15 0 10000
    10 5 3
    2 5 3
    3 5 3
    4 5 3
    5 9 6
    5 6 2
    5 7 2
    5 8 2
    6 9 4
    7 9 4
    8 9 4
    1 10 1
    1 2 1
    1 3 1
    1 4 1
    
    没思路 
    暴力...
    强过样例 
    */
    
  • 相关阅读:
    恶意代码分析实战-确认EXE什么时候编译的
    恶意代码分析-工具收集
    Bug Bounty Reference
    [ Mongodb ] 问题总汇
    [ kvm ] 四种简单的网络模型
    [ kvm ] 进程的处理器亲和性和vCPU的绑定
    虚拟化概念总结
    centos7安装tengine强制使用HTTPS访问
    [ SSH 两种验证方式原理 ]
    [ Centos 7 iscsi搭建 及 1台客户端同时挂载多台iscsi服务端问题 ]
  • 原文地址:https://www.cnblogs.com/blank-space-/p/14860837.html
Copyright © 2011-2022 走看看