Codeforces Round #530 (Div. 2)[A,B,C,D]

A. Snowball

Today’s morning was exceptionally snowy. Meshanya decided to go outside and noticed a huge snowball rolling down the mountain! Luckily, there are two stones on that mountain.
Initially, snowball is at height h and it has weight w. Each second the following sequence of events happens: snowball’s weights increases by i, where i — is the current height of snowball, then snowball hits the stone (if it’s present at the current height), then snowball moves one meter down. If the snowball reaches height zero, it stops.
There are exactly two stones on the mountain. First stone has weight u1 and is located at height d1, the second one — u2 and d2 respectively. When the snowball hits either of two stones, it loses weight equal to the weight of that stone. If after this snowball has negative weight, then its weight becomes zero, but the snowball continues moving as before.
Find the weight of the snowball when it stops moving, that is, it reaches height 0.
Input
First line contains two integers w and h — initial weight and height of the snowball (0≤w≤100; 1≤h≤100).
Second line contains two integers u1 and d1 — weight and height of the first stone (0≤u1≤100; 1≤d1≤h).
Third line contains two integers u2 and d2 — weight and heigth of the second stone (0≤u2≤100; 1≤d2≤h; d1≠d2). Notice that stones always have different heights.
Output
Output a single integer — final weight of the snowball after it reaches height 0.

題意:雪球在高度爲h的山上往下滾落,過程中會與兩塊高度分別爲d1, d2的石頭碰撞,碰撞過程雪球減少與石頭相同的重量。開始雪球重量爲w,每下落一米雪球都會增加當前高度的重量,當雪球與石頭碰撞時重量小於石頭時,雪球質量會變爲0後繼續往下滾動,求雪球在高度爲0時的重量是多少?
題解:水題,直接模擬一遍。
code:

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
	int w, h, u1, d1, u2, d2;
	scanf("%d%d%d%d%d%d", &w, &h, &u1, &d1, &u2, &d2);
	for(int i = h; i > 0; i--){
		w+=i;
		if(i==d1) w-=u1;
		else if(i==d2) w-=u2;
		if(w<0){
			w = 0;
		}
	}
	printf("%d\n", w);
	return 0;
} 

B. Squares and Segments

Little Sofia is in fourth grade. Today in the geometry lesson she learned about segments and squares. On the way home, she decided to draw n squares in the snow with a side length of 1. For simplicity, we assume that Sofia lives on a plane and can draw only segments of length 1, parallel to the coordinate axes, with vertices at integer points.
In order to draw a segment, Sofia proceeds as follows. If she wants to draw a vertical segment with the coordinates of the ends (x,y) and (x,y+1). Then Sofia looks if there is already a drawn segment with the coordinates of the ends (x′,y) and (x′,y+1) for some x′. If such a segment exists, then Sofia quickly draws a new segment, using the old one as a guideline. If there is no such segment, then Sofia has to take a ruler and measure a new segment for a long time. Same thing happens when Sofia wants to draw a horizontal segment, but only now she checks for the existence of a segment with the same coordinates x, x+1 and the differing coordinate y.
Sofia is in a hurry, so she wants to minimize the number of segments that she will have to draw with a ruler without a guide. Help her find this minimum number.
Input
The only line of input contains a single integer n (1≤n≤10^9), the number of squares that Sofia wants to draw.
Output
Print single integer, the minimum number of segments that Sofia will have to draw with a ruler without a guide in order to draw n squares in the manner described above.

code:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			if(i*j>=n){
				printf("%d\n", i+j);
				return 0;
			}
		}
	}
	return 0;
} 

C. Postcard

Andrey received a postcard from Irina. It contained only the words “Hello, Andrey!”, and a strange string consisting of lowercase Latin letters, snowflakes and candy canes. Andrey thought that this string is an encrypted message, and decided to decrypt it.
Andrey noticed that snowflakes and candy canes always stand after the letters, so he supposed that the message was encrypted as follows. Candy cane means that the letter before it can be removed, or can be left. A snowflake means that the letter before it can be removed, left, or repeated several times.
Andrey knows that messages from Irina usually have a length of k letters. Help him to find out if a given string can encode a message of k letters, and if so, give an example of such a message.
For example, consider the following string: hw?ap*yn?eww*ye*ar
This string can encode the message «happynewyear». For this, candy canes and snowflakes should be used as follows:

  • candy cane 1: remove the letter w,
  • snowflake 1: repeat the letter p twice,
  • candy cane 2: leave the letter n,
  • snowflake 2: remove the letter w,
  • snowflake 3: leave the letter e.

題意:Andrey有一串密碼串僅包含小寫字母與‘ * ’,‘?’,‘ * ’表示前面的小寫字母可以被刪除、保留或者重複任意次;‘ ?’表示前面的小寫字母可以被保留或者刪除,並且滿足兩個特殊符號前面必然爲小寫字母。問密碼串能否被解析成只有k個字符的字符串(只包含小寫字母)
題解:可以分成四種情況討論,我們設當前密碼串中小寫字母的數量爲up:

  • 當up < k時,表示解析出來的字符串比當前密碼串中的小寫字母多。
    • 若當前密碼串不存在‘ * ’,則無解,輸出‘Impossible’
    • 若當前密碼串存在‘ * ’,則可以解析。在第一個出現 ’ * '的位置重複(k-up)個小寫字母,其他特殊符號去掉即可。
  • 當up >= k時,表示解析出來的字符串比當前密碼串中的小寫字母少。
    • 若當前密碼串特殊符號總數<(k-up),則無解。輸出‘Impossible’
    • 若當前密碼串特殊符號總數>(k-up),則可以解析。將前(k-up)個特殊符號前面的小寫字母去掉其餘保留即可。

code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
	char s[210];
	int k;
	scanf("%s%d", s, &k);
	int up = 0, t1 = 0, t2 = 0, len = strlen(s);
	for(int i = 0; i < len; i++){
		if('a' <= s[i] && s[i] <= 'z') up++;
		else if(s[i] == '?') t1++;
		else t2++;
	} 
	if(k <= up){
		int f = up-k;
		if(f > t1+t2) printf("Impossible\n");
		else{
			for(int i = 0; i < len; i++){
				if((i+1!=len && (s[i+1]=='?' || s[i+1]=='*') && f > 0)){
					f--;
					continue;
				}
				else if(s[i]=='?' || s[i]=='*') continue;
				printf("%c", s[i]);
			}
		}
	}
	else{
		if(!t2) printf("Impossible\n");
		else{
			bool flag = true;
			int f = k-up;
			for(int i = 0; i < len; i++){
				if(i+1!=len && s[i+1]=='*' && flag == true){
					for(int j = 0; j <= f; j++) printf("%c", s[i]);
					flag = false;
					continue;
				}
				else if(s[i]=='?' || s[i]=='*') continue;
				printf("%c", s[i]);
			}
		}
	}
	return 0;
} 

D. Sum in the tree

Mitya has a rooted tree with n vertices indexed from 1 to n, where the root has index 1. Each vertex v initially had an integer number av≥0 written on it. For every vertex v Mitya has computed sv: the sum of all values written on the vertices on the path from vertex v to the root, as well as hv — the depth of vertex v, which denotes the number of vertices on the path from vertex v to the root. Clearly, s1=a1 and h1=1.
Then Mitya erased all numbers av, and by accident he also erased all values sv for vertices with even depth (vertices with even hv). Your task is to restore the values av for every vertex, or determine that Mitya made a mistake. In case there are multiple ways to restore the values, you’re required to find one which minimizes the total sum of values av for all vertices in the tree.
Input
The first line contains one integer n — the number of vertices in the tree (2≤n≤1e5). The following line contains integers p2, p3, … pn, where pi stands for the parent of vertex with index i in the tree (1≤pi<i). The last line contains integer values s1, s2, …, sn (−1≤sv≤1e9), where erased values are replaced by −1.
Output
Output one integer — the minimum total sum of all values av in the original tree, or −1 if such tree does not exist.

題意:有一顆樹每一個頂點都存在av,sv,hv值。

  • av:頂點權值
  • sv:頂點到根節點av的總和
  • hv:頂點的深度

規定頂點1爲根結點且其深度爲1。Mitya將樹的av值全部抹去,還有深度爲偶數的所有sv值抹去。問樹所有頂點av值總和最小是多少?
題解:對數據建邊,DFS從頂點1開始找其孩子頂點。
則頂點深度爲偶數的sv值爲其所有孩子頂點中與其父頂點sv的差的最小值加上父頂點的sv值。
最後枚舉一遍對每一個頂點的av(sv-su)求和。注意使用Long long!!!
code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e5+10;
const long long INF = 0x3f3f3f3f3f3f3f3f;
int tree[maxn];
long long w[maxn];
struct Edge{
	int v, next;
}edge[maxn];
int head[maxn], cnt;
void init(){
	cnt = 0;
	memset(head, -1, sizeof(head));
}
void addEdge(int u, int v){
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
void dfs(int idx, int now, int u){
	if(now){
		for(int i = head[idx]; i != -1; i = edge[i].next){
			int v = edge[i].v;
			dfs(v, now^1, idx);
		}
	}
	else{
		long long Min = INF;
		for(int i = head[idx]; i != -1; i = edge[i].next){
			int v = edge[i].v;
			Min = min(Min, w[v]-w[u]);
			dfs(v, now^1, idx);
		}
		w[idx] = Min!=INF?Min+w[u]:0+w[u];
	}
}
int main(){
	init();
	int n;
	tree[1] = 0;
	scanf("%d", &n);
	for(int i = 2; i <= n; i++){
		scanf("%d", &tree[i]);
		addEdge(tree[i], i);
	}
	for(int i = 1; i <= n; i++){
		scanf("%lld", &w[i]);
	}
	
	dfs(1, 1, -1);
	long long ans = 0;
	for(int i = 1; i <= n; i++){
		ans+=w[i]-w[tree[i]];
		if(w[i]-w[tree[i]]<0){
			printf("-1\n");
			return 0;
		}
	}
	printf("%lld\n", ans);
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章