1. 程式人生 > 實用技巧 >2020-12-9 and 2020-12-10

2020-12-9 and 2020-12-10

2020upc第二十五場組隊訓練

問題 C: Dessert Café時間限制: 1 Sec 記憶體限制: 128 MB
提交 狀態

題目描述

Kim, who wishes to start a business, is trying to open a dessert cafe he has been preparing after graduating from college. The road network in the town where Kim lives forms a tree structure, that is, a connected acyclic graph as shown in the figure below. There are n candidate sites for a dessert café in the town. In the figure below, a circle represents a candidate site for a dessert café, a line segment between two candidate sites represents a road, and the value labeled on a line segment represents the length of a road.

There are k apartment complexes in this town, so he wants his dessert café to be located as close as possible to an apartment complex. In above figure, there are three apartment complexes which are located to the candidate sites labeled by A, B, and C. Considering the competitiveness and profitability, he thinks that a candidate site satisfying the following condition is a good place.

Let d(x, y) be the length of the shortest path on a road network between two candidate sites x and y. A candidate site p is a good place if there exists a candidate site z where an apartment complex is located such that d(p, z) < d(q, z) for each candidate site q (≠ p).

In above figure, candidate sites 2, 4, 5, 6, 8, and 9 are good places. More specifically, for example, candidate 6 is a good place because it is closer to apartment complex B than any other candidate sites except for candidate 5, and is closer to apartment complex A than candidate 5. That is, there exists apartment complex B on candidate 5 satisfying d(6, 5) < d(q, 5) for q ∈ {1, 2, 3, 4, 7, 8, 9}, and there exists apartment complex A on candidate 2 satisfying d(6, 2) < d(5, 2). Candidate 7 is not a good place because none of apartment complexes are closer than candidate 6.

Given the information on candidate sites and apartment complexes in the town, write a program to output the number of good places.

輸入

Your program is to read from standard input. The input starts with a line containing two integers, n and k (3 ≤ n ≤ 100,000 , 1 ≤ k ≤ n), where n is the number of candidate sites and k is the number of apartment complexes. The candidate sites are numbered from 1 to n. In the following n − 1 lines, each line contains three integers, i, j, and w (1 ≤ i,j ≤ n, 1 ≤ w ≤ 1,000), where i and j are candidate sites and w is the length of the road between i and j. The last line contains k integers which represent the locations of apartment complexes in the town.

輸出

Your program is to write to standard output. Print exactly one line. The line should contain the number of good places.

樣例輸入 [Copy](javascript:CopyToClipboard($('#sampleinput').text()))

【樣例1】
9 3
1 2 8
2 4 7
4 3 6
4 6 4
5 6 3
6 7 2
6 9 5
9 8 6
2 5 8
【樣例2】
4 4
1 2 1
1 3 1
1 4 1
2 4 1 3

樣例輸出 [Copy](javascript:CopyToClipboard($('#sampleoutput').text()))

【樣例1】
6
【樣例2】
4

換根dp,發現k個點,兩兩之間路徑上的點到k個點的長度和是一樣的,並且還是最短的,裸的換根dp

/*
 *@author spnooyseed
 */
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3 , "Ofast" , "inline")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#include <bitset>
#include <deque>
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0)
#define x first
#define y second
#define pb push_back
#define ls rt << 1
#define rs rt << 1 | 1
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 2e5 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
int e[N] , ne[N] , w[N] , h[N] , idx , n , m , vis[N] ;
void add(int a , int b , int c) {
  e[idx] = b , ne[idx] = h[a] , w[idx] = c , h[a] = idx ++ ;
}
ll dp[N] ;
void dfs(int u , int f){
  for(int i = h[u] ; ~i ; i = ne[i]) {
    int v = e[i] ;
    if(v == f) continue ;
    dfs(v , u) ;
    if(dp[v] || vis[v])
      dp[u] += dp[v] + w[i] ;
  }
  return ;
}
void dfs1(int u , int f , ll sum) {
  dp[u] += sum ;
  for(int i = h[u] ; ~i ; i = ne[i]) {
    int v = e[i] ;
    if(v == f) continue ;
    ll x = dp[u] - dp[v] - w[i] ;
    ll res = x == 0 ? (vis[u] ? w[i] : 0 ) : x + w[i] ;
    if(dp[v] || vis[v])
      dfs1(v , u , res) ;
  }
}
int work()
{
  scanf("%d%d" , &n , &m) ;
  memset(h , -1 , sizeof h) ;
  for(int i = 1; i < n ;i ++ ) {
    int a , b , c ;
    scanf("%d%d%d" , &a , &b , &c) ;
    add(a , b , c) , add(b , a , c) ;
  }
  int res , ans = 0 ;
  for(int i = 1; i <= m ;i ++ ) {
    int x ;
    scanf("%d" , &x) ;
    res = x ;
    vis[x] = 1;
  }
  if(m == 1) {
    return 0 * puts("1") ;
  }
  dfs(1 , 0) ;
  dfs1(1 , 0 , 0) ;
  for(int i = 1; i <= n ;i ++ )
   if(dp[i] == dp[res]) ans ++ ;
  cout << ans << "\n" ;
  return 0 ;
}
int main()
{
    // freopen("C://Users//spnooyseed//Desktop//27.in" , "r" , stdin) ;
  //   freopen("C://Users//spnooyseed//Desktop//out.txt" , "w" , stdout) ;
 
  work() ;
  return 0 ;
}
/*
9 1
1 2 8
2 4 7
4 3 6
4 6 4
5 6 3
6 7 2
6 9 5
9 8 6
2
*/

問題 L: Two Buildings時間限制: 1 Sec 記憶體限制: 512 MB
提交 狀態

題目描述

There are n buildings along a horizontal street. The buildings are next to each other along the street, and the i-th building from left to right has width 1 and height hi. Among the n buildings, we are to find two buildings, say the i-th building and j-th building with i < j, such that (hi + hj) × (j − i) is maximized.

For example, the right figure shows 5 buildings, with heights 1, 3, 2, 5, 4, from left to right. If we choose the first 2 buildings, then we get (1 + 3) × (2 − 1) = 4. If we choose the first and fifth buildings, then we (1 + 4) × (5 − 1) = 20. The maximum value is achieved by the second and fifth buildings with heights 3 and 4, respectively: (3 + 4) × (5 − 2) = 21.

Write a program that, given a sequence of building heights, prints max1≤i<j≤n(hi + hj) × (j − i).

輸入

Your program is to read from standard input. The input starts with a line containing an integer n (2 ≤ n ≤ 1,000,000), where n is the number of buildings. The buildings are numbered 1 to n from left to right. The second line contains the heights of n buildings separated by a space such that the i-th number is the height hi of the i-th building (1 ≤ hi ≤ 1,000,000).

輸出

our program is to write to standard output. Print exactly one line. The line should contain max1≤i<j≤n(hi + hj) × (j − i).

樣例輸入 [Copy](javascript:CopyToClipboard($('#sampleinput').text()))

【樣例1】
5
1 3 2 5 4
【樣例2】
5
8 3 6 3 1

樣例輸出 [Copy](javascript:CopyToClipboard($('#sampleoutput').text()))

【樣例1】
21
【樣例2】
36

提交狀態

2017年icpc WF原題D題稍微改了改,改了一個符號,不講武德。

/*
 *@author spnooyseed
 */
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3 , "Ofast" , "inline")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#include <bitset>
#include <deque>
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0)
#define x first
#define y second
#define pb push_back
#define ls rt << 1
#define rs rt << 1 | 1
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<ll , ll> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
PII a[N] , b[N] , c[N] ;
int n , m ;
ll check(int x , int y) {
  if(a[x].x > b[y].x && a[x].y > b[y].y) return 0 ;
  return 1ll * (b[y].x - a[x].x) * (b[y].y - a[x].y) ;
}
ll merge_sort(int L , int R , int l , int r) {
  if(L > R || l > r) return 0 ;
  int mid = L + R >> 1 ;
  int pos = l ;
  ll ans = 0 ;
  for(int i = l ;i <= r ;i ++ )
    if(check(mid , i) > check(mid , pos)) pos = i , ans = check(mid , i) ;
  return max({merge_sort(L , mid - 1 , l , pos) , merge_sort(mid + 1 , R , pos  , r) , check(mid , pos)});
}
bool cmp(PII a , PII b) {
  if(a.y != b.y) return a.y < b.y ;
  return a.x < b.x ;
}
int work()
{
  scanf("%d" , &n) ;
  m = n ;
  for(int i = 1 , x ; i <= n ;i ++ ) {
    scanf("%d" , &x) ;
    a[i] = {-x , i} ;
    b[i] = {x , i} ;
  }
  int idx1 = 0 ;
  sort(a + 1 , a + n + 1 , cmp) ;
  for(int i = 1; i <= n ;i ++ ) {
    if(!idx1 || a[idx1].y != a[i].y) a[++ idx1] = a[i] ;
  }
  n = 0 ;
  for(int i = 1; i <= idx1 ;i ++ )
    if(!n || a[i].x < a[n].x) a[++ n] = a[i] ;
  idx1 = 0 ;
  sort(b + 1 , b + m + 1 , cmp) ;
  for(int i = 1; i <= m ;i ++ ) {
    if(!idx1 || b[idx1].y != b[i].y) b[++ idx1] = b[i] ;
    else b[idx1] = b[i] ;
  }
  m = 0 ;
  for(int i = idx1 ; i >= 1 ;i -- ) {
      if(!m || c[m].x < b[i].x) c[++ m] = b[i] ;
  }
  reverse(c + 1 , c + m + 1) ;
  for(int i = 1; i <= m ;i ++ ) b[i] = c[i] ;
  ll ans = merge_sort(1 , n , 1 , m) ;
  cout << ans << "\n" ;
  return 0 ;
}
int main()
{
    // freopen("C://Users//spnooyseed//Desktop//in.txt" , "r" , stdin) ;
  //   freopen("C://Users//spnooyseed//Desktop//out.txt" , "w" , stdout) ;
  work() ;
  return 0 ;
}
/*
*/
 

連結:https://ac.nowcoder.com/acm/problem/214460
來源:牛客網

Triangle Numbers

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

三角形是由同一平面內不在同一直線上的三條線段'首尾'順次連線所組成的封閉圖形,在數學、建築學有應用。

常見的三角形按邊分有普通三角形(三條邊都不相等),等腰三角形(腰與底不等的等腰三角形、腰與底相等的等腰三角形即等邊三角形);按角分有直角三角形、銳角三角形、鈍角三角形等,其中銳角三角形和鈍角三角形統稱斜三角形。

定義 "三角形"數:如果一個十進位制正整數,可以從它的數位中取出三個數字a,b,c,能構成合法的三角形,則稱該正整數為"三角形"數。

比如正整數345就是一個"三角形"數,3,4,5分別作為三角形的三條邊,組成了一個(直角)三角形。

比如正整數123不是"三角形"數,因為1,2,3三條邊無法構成合法的三角形。

現給定區間[A,B],求區間內"三角形"數的個數。

輸入描述:

第一行輸入一個整數T代表T組案例


接下來T行,每行兩個正整數 A,B


(T≤1000,1≤A≤B≤109)(T \leq 1000, 1 \leq A \leq B \leq 10^9)(T≤1000,1≤A≤B≤109)

輸出描述:

輸出T行,每一行表示對應區間內的 "三角形"數的個數。

示例1

輸入

[複製](javascript:void(0)