EOJ Monthly 2021.1

EOJ Monthly 2021.1

2/6

2021快乐,期末考加油——


B想通了比C简单

C思路没问题但是不知道为什么一直WA19


B - 洪水

B. 洪水 - EOJ Monthly 2021.1 Sponsored by TuSimple - ECNU Online Judge

刚开始的想法是二分+bfs(必T啊

然后还不信邪冲了一发,T1

有点cf思维题的感觉

其实数据范围给的很清楚的是思维题

官方题解 : 考虑终点 (c,d) 未被淹没的最晚时刻 T。我们可以证明,以 (a,b) 为起点的最晚出发时刻是 T−|a−c|−|b−d|。换句话说, Cuber 出现后可以沿着最短路径不停地走,并且到达终点后的下一时刻终点被淹没。

为什么一定可行呢?考虑 t 时刻 Cuber 站在 (x,y) 的情况。因为此时 (x,y) 未被淹没,所以在 t−1 时刻 (x,y) 的相邻格子也未被淹没(如果某相邻格子在 t−1 时刻被淹没,那么 (x,y) 必会在 t 时刻被淹没,故矛盾)。所以,如果 “时光倒流”,Cuber 就能自由移动,我们就能轻易推得上述结论了。

时间复杂度 O(nq),可优化到 O((n+q)log⁡n)。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 110;

struct node {
    
    
	int t, x, y;
}mp[maxn];

int main() {
    
    
	int n, q;
	cin >> n >> q;
	for(int i = 1; i <= n; ++ i) {
    
    
		cin >> mp[i].t >> mp[i].x >> mp[i].y;
	}
	
	while(q--) {
    
    
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		int mn = 1e9;
		
		for(int i = 1; i <= n; ++i) {
    
    
			mn = min(mn, mp[i].t + abs(c - mp[i].x) + abs(d - mp[i].y));
		}
		
		cout << mn - abs(a - c) - abs(b - d) - 1 << endl;
	}
} 

C - 魔树

C. 魔树 - EOJ Monthly 2021.1 Sponsored by TuSimple - ECNU Online Judge

疯狂wa19,不肯重构,赛后看到题解思路没问题,先放一放8

看到提交里有个代码感觉写的很清楚:

#include <bits/stdc++.h>
using namespace std;

long long MOD = 1e9 + 7;

const int maxn = 1e5 + 10; 
vector<int> edge[maxn];
int m,n,p=0;
// p:总层数 
int leaves[maxn];
vector<long long> ans;

int DFS(int root,int g){
    
    
    int ans=0;
    for(int i=0;i<edge[root].size();i++){
    
    
        int current = edge[root][i];
		if(current==g)continue;
        int c=DFS(current,root);  
        ans = ans>c+1?ans:c+1;
    }
    p=p>ans?p:ans;
    leaves[ans]++;
    return ans; // 返回该节点所在的层数 
}

int main(){
    
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)edge[i].clear();
    for(int i=1;i<n;i++){
    
    
        int a,b;
        scanf("%d%d",&a,&b);
        edge[a].push_back(b);
		edge[b].push_back(a);
    }
    for(int i=0;i<n;i++)leaves[i]=0;
    DFS(1,-1);
    for(int i=p;i>=0;i--){
    
    
        ans.push_back(leaves[i]);
    }
	
    for(int i = 0;i<m;i++){
    
    
        int t;
		char f='c';
		while(f!='A'&&f!='D')scanf("%c",&f);
        if(f=='A'){
    
    
            scanf("%d",&t);
            ans.push_back(ans.back()*t%MOD);
        }else{
    
    
            ans.pop_back();
        }
    }
    int res=0;
    for(int i=0;i<ans.size();i++){
    
    
		res+=ans[i];
		res%=MOD;
    }
    printf("%d\n",res);
}

猜你喜欢

转载自blog.csdn.net/qq_39602052/article/details/112134653