每日两刷Codeforces Round #551 (Div. 2) (B. Serval and Toy 模拟),C. Serval and Parenthesis(贪心))2019/4/14

B. Serval and Toy Bricks

time limit per test 1 second
memory limit per test 256 megabytes
input standard input
output standard output
Luckily, Serval got onto the right bus, and he came to the kindergarten on time. After coming to kindergarten, he found the toy bricks very funny.
He has a special interest to create difficult problems for others to solve. This time, with many 1×1×1 toy bricks, he builds up a 3-dimensional object. We can describe this object with a n×m matrix, such that in each cell (i,j), there are hi,j bricks standing on the top of each other.
However, Serval doesn’t give you any hi,j, and just give you the front view, left view, and the top view of this object, and he is now asking you to restore the object. Note that in the front view, there are m columns, and in the i-th of them, the height is the maximum of h1,i,h2,i,…,hn,i. It is similar for the left view, where there are n columns. And in the top view, there is an n×m matrix ti,j, where ti,j is 0 or 1. If ti,j equals 1, that means hi,j>0, otherwise, hi,j=0.
However, Serval is very lonely because others are bored about his unsolvable problems before, and refused to solve this one, although this time he promises there will be at least one object satisfying all the views. As his best friend, can you have a try?

Input

The first line contains three positive space-separated integers n,m,h (1≤n,m,h≤100) — the length, width and height.
The second line contains m non-negative space-separated integers a1,a2,…,am, where ai is the height in the i-th column from left to right of the front view (0≤ai≤h).
The third line contains n non-negative space-separated integers b1,b2,…,bn (0≤bj≤h), where bj is the height in the j-th column from left to right of the left view.
Each of the following n lines contains m numbers, each is 0 or 1, representing the top view, where j-th number of i-th row is 1 if hi,j>0, and 0 otherwise.
It is guaranteed that there is at least one structure satisfying the input.

Output

Output n lines, each of them contains m integers, the j-th number in the i-th line should be equal to the height in the corresponding position of the top view. If there are several objects satisfying the views, output any one of them.

Examples
input

3 7 3
2 3 0 0 2 0 1
2 1 3
1 0 0 0 1 0 0
0 0 0 0 0 0 1
1 1 0 0 0 0 0

output

1 0 0 0 2 0 0
0 0 0 0 0 0 1
2 3 0 0 0 0 0

input

4 5 5
3 5 2 0 4
4 2 5 4
0 0 0 0 1
1 0 1 0 0
0 1 0 0 0
1 1 1 0 0

output

0 0 0 0 4
1 0 2 0 0
0 5 0 0 0
3 4 1 0 0

Note

在这里插入图片描述
The graph above illustrates the object in the first example.
在这里插入图片描述
在这里插入图片描述

The first graph illustrates the object in the example output for the second example, and the second graph shows the three-view drawing of it.

题目大意:

由前视图,左视图的各行的高度,和俯视图是否存在,来推出积木的形状。

题目思路:

以俯视图为主体,每行每列都比较一下主视图和侧视图的最小值,即是结果。

扫描二维码关注公众号,回复: 5968513 查看本文章
#include<bits/stdc++.h>
using namespace std;
const int N=107;
int n,m,h,mp[N][N],a[N],b[N],i,j,k;
int main(){
	for(scanf("%d%d%d",&n,&m,&h),i=1;i<=m;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i)scanf("%d",b+i);
	for(i=1;i<=n;++i)
	for(j=1;j<=m;++j){
		scanf("%d",&mp[i][j]);
		if(mp[i][j])mp[i][j]=min(a[j],b[i]);
	}
	for(i=1;i<=n;++i,puts(""))
	for(j=1;j<=m;++j)
	printf("%d ",mp[i][j]);
}

还跑去看了一下大佬python的代码嘻嘻(太厉害了):
enumerate
对可迭代对象进行枚举,enumerate的参数是一个可迭代对象,每次返回一个元组,这个元组长这样:(索引,可迭代对象的元素)。

n, m, h = map(int, input().split()) 
a = list(map(int, input().split()))
b = list(map(int, input().split()))
for i in range(n):
    print(*(map(lambda z: z[1] * min(a[z[0]], b[i]), enumerate(map(int, input().split()))))) 

(本人是个python初学者)

>>> nums = map(int, input().split())
19 7 8 25
>>> nums
[19 7 8 25] #返回一个集合

还是不怎么看得懂QAQ

C. Serval and Parenthesis Sequence

题目链接: http://codeforces.com/contest/1153/problem/C
time limit per test 1 second
memory limit per test 256 megabytes
input standard input
output standard output
Serval soon said goodbye to Japari kindergarten, and began his life in Japari Primary School.
In his favorite math class, the teacher taught him the following interesting definitions.
A parenthesis sequence is a string, containing only characters “(” and “)”.
A correct parenthesis sequence is a parenthesis sequence that can be transformed into a correct arithmetic expression by inserting characters “1” and “+” between the original characters of the sequence. For example, parenthesis sequences “()()”, “(())” are correct (the resulting expressions are: “(1+1)+(1+1)”, “((1+1)+1)”), while “)(” and “)” are not. Note that the empty string is a correct parenthesis sequence by definition.
We define that |s| as the length of string s. A strict prefix s[1…l] (1≤l<|s|) of a string s=s1s2…s|s| is string s1s2…sl. Note that the empty string and the whole string are not strict prefixes of any string by the definition.
Having learned these definitions, he comes up with a new problem. He writes down a string s containing only characters “(”, “)” and “?”. And what he is going to do, is to replace each of the “?” in s independently by one of “(” and “)” to make all strict prefixes of the new sequence not a correct parenthesis sequence, while the new sequence should be a correct parenthesis sequence.
After all, he is just a primary school student so this problem is too hard for him to solve. As his best friend, can you help him to replace the question marks? If there are many solutions, any of them is acceptable.

Input

The first line contains a single integer |s| (1≤|s|≤3⋅105), the length of the string.
The second line contains a string s, containing only “(”, “)” and “?”.

Output

A single line contains a string representing the answer.
If there are many solutions, any of them is acceptable.
If there is no answer, print a single line containing “: (” (without the quotes).

Examples
input

6
(???

output

(()())

input

10
(???(???(?

output

: (

Note

It can be proved that there is no solution for the second sample, so print “: (”.

题目大意:

给你一串字符串,含有(,),?,将?改为(或),前缀不能满足正确的括号序列。(如(),(())之类的),但整个字符串是正确的表达式,可能实现则输出结果。

题目思路:

先填(,再填),按不超过一半来填,将不符合的删去。

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
char s[300007];
int n,cnt,l;
int main(){
    scanf("%d %s",&n,s+1);
    if(n%2==1) return 0*puts(":(");
    for(int i=1;i<=n;i++) if(s[i]=='(') l++;
    for(int i=1;i<=n;i++)if(s[i]=='?'&&l<n/2)l++,s[i]='(';
    for(int i=1;i<=n;i++)if(s[i]=='?')s[i]=')';
    for(int i=1;i<=n;i++){
        if(s[i]=='(') cnt++;
        else{
            cnt--;
            if(cnt==0&&i!=n||cnt<0) return 0*puts(":(");
        }
    }
    if(!cnt) return 0*puts(s+1);
    else return 0*puts(":(");
}

D. Serval and Rooted Tree

time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output
Now Serval is a junior high school student in Japari Middle School, and he is still thrilled on math as before.
As a talented boy in mathematics, he likes to play with numbers. This time, he wants to play with numbers on a rooted tree.
A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a node v is the last different from v vertex on the path from the root to the vertex v. Children of vertex v are all nodes for which v is the parent. A vertex is a leaf if it has no children.
The rooted tree Serval owns has n nodes, node 1 is the root. Serval will write some numbers into all nodes of the tree. However, there are some restrictions. Each of the nodes except leaves has an operation max or min written in it, indicating that the number in this node should be equal to the maximum or minimum of all the numbers in its sons, respectively.
Assume that there are k leaves in the tree. Serval wants to put integers 1,2,…,k to the k leaves (each number should be used exactly once). He loves large numbers, so he wants to maximize the number in the root. As his best friend, can you help him?

Input

The first line contains an integer n (2≤n≤3⋅105), the size of the tree.
The second line contains n integers, the i-th of them represents the operation in the node i. 0 represents min and 1 represents max. If the node is a leaf, there is still a number of 0 or 1, but you can ignore it.
The third line contains n−1 integers f2,f3,…,fn (1≤fi≤i−1), where fi represents the parent of the node i.

Output

Output one integer — the maximum possible number in the root of the tree.

Examples
input

6
1 0 1 1 0 1
1 2 2 2 2

output

1

input

5
1 0 1 0 1
1 1 1 1

output

4

input

8
1 0 0 1 0 1 1 0
1 1 2 2 3 3 3

output

4

input

9
1 1 0 0 1 0 1 0 1
1 1 2 2 3 3 4 4

output

5

Note

Pictures below explain the examples. The numbers written in the middle of the nodes are their indices, and the numbers written on the top are the numbers written in the nodes.
In the first example, no matter how you arrange the numbers, the answer is 1.
在这里插入图片描述
In the second example, no matter how you arrange the numbers, the answer is 4.
在这里插入图片描述
In the third example, one of the best solution to achieve 4 is to arrange 4 and 5 to nodes 4 and 5.
在这里插入图片描述
In the fourth example, the best solution is to arrange 5 to node 5.
在这里插入图片描述

题目大意:

给你一棵树,每个节点有对应的操作(max,min)如果节点是叶,但可以忽略它。,给出每个节点的父节点。输出树根的最大可能数。

题目思路:

如果我们想检查x是否是答案,那么我们可以将所有不小于x的数字设置为1,将小于x的数字设置为0。然后我们可以用dpi来表示i的子树中,i节点上的最大个数是i子树中叶数最少的dpi,i子树中至少应该有dpi,这样i节点上的个数就是1。那么K+1−dp1是最终答案。复杂性O(n)

#include <cstdio>
using namespace std;
struct node{
	int to;
	node *next;
};
int i,j,m,n,a[1000005],f[1000005],dp[1000005],deg[1000005],k;
node *nd[1000005];
void addd(int u,int v){
	node *p=new node();
	p->to=v;
	p->next=nd[u];
	nd[u]=p;
}
void dfs(int u){
	node *p=nd[u];
	if ((u>1)&&(deg[u]==1)){//note that u>1
		dp[u]=1;
		k++;
		return;
	}
	if (a[u]) dp[u]=1000000000;
	else dp[u]=0;
	while(p){
		dfs(p->to);
		if (a[u]){
			if (dp[p->to]<dp[u]) dp[u]=dp[p->to];
		}else{
			dp[u]+=dp[p->to];
		}
		p=p->next;
	}
}
int main(){
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(i=2;i<=n;i++){
		scanf("%d",&f[i]);
		deg[i]++;
		deg[f[i]]++;
		addd(f[i],i);
	}
	dfs(1);
	printf("%d\n",k+1-dp[1]);
	return 0;
}

叶子节点dp[i]=1
如果节点取max则dp[i]=min(dp[子节点们])
如果取min则dp[i]+=dp[子节点们]
答案就是 叶子节点个数+1-dp[1]

#include<bits/stdc++.h>
#include<vector>
using namespace std;
vector<int> g[300005];
int dp[300005];
int a[300005];
map<int,int>vis;
void dfs(int now) {
 
	if(g[now].size()==0) {
		dp[now]=1;
		return ;
	}
	if(a[now]==1) {
		dp[now]=0x3f3f3f3f;
		for(int i=0; i<g[now].size(); i++) {
			dfs(g[now][i]);
			dp[now]=min(dp[now],dp[g[now][i]]);
		}
	} else {
		for(int i=0; i<g[now].size(); i++) {
			dfs(g[now][i]);
			dp[now]+=dp[g[now][i]];
		}
	}
	return ;
}
int main() {
	int n;
	cin>>n;
	int cnt=n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
	}
 
	for(int i=2; i<=n; i++) {
		int fa;
		cin>>fa;
		if(!vis[fa]) {
			cnt--,vis[fa]=1;
		}
		g[fa].push_back(i);
	}
	dfs(1);
	cout<<cnt+1-dp[1];
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43333395/article/details/89304720