1. 程式人生 > >Codeforces Round #527 (Div. 3)D,F;

Codeforces Round #527 (Div. 3)D,F;

D題:是一個思維題,同時也是一個數據結構,首先要知道什麼情況對,是否可以新增到一個高度有影響,首先想到的是就是如果兩個數相鄰,且他們相差為奇數,這是就不可以疊到一樣高,但是如果2, 1, 1這種情況就可以所以如果奇數出現,偶數次且相鄰這是就可以平成任意的高度,這是這兩個柱子就不需要考慮。可以消掉,這是·就繼續往下考慮;這就相當於一個棧的結構。

從這裡可以知道,奇數對是否成功有影響,1,3,5他們都是等價的所以都變為1, 也就是對所有的書對二取餘,預處理之後就開始站的操作,如果壓入棧中的數再次出現,且等於s.top(),這是就是這個數pop()除去,不斷進行這樣的操作,最後判斷棧中的數的個數,如果大於1就是輸出“NO”,否則輸出“YES”;

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n;
stack<int>s;
int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	int a;
	while(n--){
		cin >> a;
		a = a%2;
		if(s.size() > 0 && s.top() == a){
			s.pop();
		}else s.push(a);
	}
	if(s.size() > 1)cout << "NO"<< endl;
	else cout << "YES" << endl;
	return 0;
}

F題是一道關於樹的題目:也就是資料結構啊,在做題時要考慮到樹的基本結構,然後要對樹有敏感,對有關樹的操作熟悉,有哪些關於樹的題型,和什麼演算法是以樹為基礎的,一般的就會有線段樹,搜尋等等,對於此題首先要如何確定更節點,是每個都嘗試一遍還是通過以某一點為基礎,來轉化其他的點,最後取最值,首先如果暴力的話就要求時間複雜的高,所以可以捨去,那麼就應該第二種方法。這是就要求對樹有深刻的認識,知道他們之間的聯絡,又題意可知要求某一點的值乘以邊的個數,那麼可不可以把乘法轉化為加法,這樣是不是就可以使用深度搜索,不斷更新,求和,=最後得出一點到值,然後在通過轉化來求出最值。

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 2e5 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
ll n;
ll a[maxn];//初始化
ll s[maxn];//求每個節點下的值
ll d[maxn];//乘積關係的轉化 
vector<ll>v[maxn];
ll k, r;
ll dfs1(int x, int y){
	s[x] = a[x];
	for(int i =0; i < v[x].size(); i ++ ){
		if(v[x][i]!=y){
			s[x] += dfs1(v[x][i], x);
			d[x] += d[v[x][i]] + s[v[x][i]];
		}
	}
	return s[x];
}

void dfs(int x, int y, ll c){
	c += k - s[x]*2;
	r = max(r,c);
	for(int i =0; i < v[x].size(); i++){
		if(v[x][i] != y){
			dfs(v[x][i],x,c);
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	for(int i = 1; i <= n; i ++)cin >> a[i];
	ll x, y;
	for(int i = 1; i < n ; i++){
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	k = dfs1(1,1);
	//cout << k << endl;
	r = d[1];
	//cout << r << endl;
	ll t = k + r;
	dfs(1,1,t);
	cout << r << endl;
	return 0;
}

還有很長的路要走,繼續加油。