1. 程式人生 > >2017ACM/ICPC亞洲區瀋陽站-重現賽(感謝東北大學)

2017ACM/ICPC亞洲區瀋陽站-重現賽(感謝東北大學)

Little Boxes

Problem Description Little boxes on the hillside.
Little boxes made of ticky-tacky.
Little boxes.
Little boxes.
Little boxes all the same.
There are a green boxes, and b pink boxes.
And c blue boxes and d yellow boxes.
And they are all made out of ticky-tacky.
And they all look just the same.  


Input The input has several test cases. The first line contains the integer t (1 ≤ t ≤ 10) which is the total number of test cases.
For each test case, a line contains four non-negative integers a, b, c and d where a, b, c, d ≤ 2^62, indicating the numbers of green boxes, pink boxes, blue boxes and yellow boxes.  


Output For each test case, output a line with the total number of boxes.  


Sample Input 4 1 2 3 4 0 0 0 0 1 0 0 0 111 222 333 404  


Sample Output 10 0 1 1070   Java 即可;
import java.math.*;

import java.util.Scanner;


public class Main {
      public static void main(String[] args) {
      Scanner cin=new Scanner(System.in);
      BigInteger a,b,c,d;
      int T;T=cin.nextInt();
      for(int i=0;i<T;i++) {
    a=cin.nextBigInteger();b=cin.nextBigInteger();c=cin.nextBigInteger();d=cin.nextBigInteger();
    BigInteger res=a.add(b).add(c).add(d);
    System.out.println(res);
      }
    }
      
}

 

 

Rabbits


Problem Description Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number line, each occupying a different integer. In a single move, one of the outer rabbits jumps into a space between any other two. At no point may two rabbits occupy the same position.
Help them play as long as possible  


Input The input has several test cases. The first line of input contains an integer t (1 ≤ t ≤ 500) indicating the number of test cases.
For each case the first line contains the integer N (3 ≤ N ≤ 500) described as above. The second line contains n integers a1 < a2 < a3 < ... < aN which are the initial positions of the rabbits. For each rabbit, its initial position
ai satisfies 1 ≤ ai ≤ 10000.
 


Output For each case, output the largest number of moves the rabbits can make.  


Sample Input 5 3 3 4 6 3 2 3 5 3 3 5 9 4 1 2 3 4 4 1 2 4 5  


Sample Output 1 1 3 0 1   前後分別掃一遍即可,取max;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/

int n;
int a[1000];
int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	int T; cin >> T;
	while (T--) {
		rdint(n);
		for (int i = 1; i <= n; i++)rdint(a[i]);
		int ans = 0;
		for (int i = 2; i < n; i++) {
			ans += (a[i + 1] - a[i] - 1);
		}
		int maxx = ans;
		ans = 0;
		for (int i = n - 1; i > 1; i--) {
			ans += (a[i] - a[i - 1] - 1);
		}
		maxx = max(maxx, ans);
		cout << maxx << endl;
	}
    return 0;
}

 

 

Heron and His Triangle

 

Problem Description

 

A triangle is a Heron’s triangle if it satisfies that the side lengths of it are consecutive integers t&#8722;1, t, t+ 1 and thatits area is an integer. Now, for given n you need to find a Heron’s triangle associated with the smallest t bigger
than or equal to n.

 

 


Input

 

The input contains multiple test cases. The first line of a multiple input is an integer T (1 ≤ T ≤ 30000) followedby T lines. Each line contains an integer N (1 ≤ N ≤ 10^30).

 

 


Output

 

For each test case, output the smallest t in a line. If the Heron’s triangle required does not exist, output -1.

 

 


Sample Input

 

4 1 2 3 4

 

 


Sample Output

 

4 4 4 4   找規律:先打表出前幾項; 可以發現 num[ i ]=num[ i-1 ]*4-num[ i-2 ]; 然後大數即可;
import java.lang.reflect.Array;
import java.math.*;

import java.util.Scanner;



public class Main {
      public static void main(String[] args) {
      Scanner cin=new Scanner(System.in);
      BigInteger N;
      int T;T=cin.nextInt();
      BigInteger num[]=new BigInteger[1000];
      num[1]=BigInteger.valueOf(4);num[2]=BigInteger.valueOf(14);
      for(int i=3;i<=500;i++)num[i]=num[i-1].multiply(BigInteger.valueOf(4)).subtract(num[i-2]);
      for(int i=0;i<T;i++) {
       N=cin.nextBigInteger();
       for(int j=1;j<=400;j++) {
    	   if(num[j].compareTo(N)>=0) {
    		   System.out.println(num[j]);break;
    	   }
       }
      }
    }
      
}

 

Tree

Problem Description Consider a un-rooted tree T which is not the biological significance of tree or plant, but a tree as an undirected graph in graph theory with n nodes, labelled from 1 to n. If you cannot understand the concept of a tree here, please omit this problem.
Now we decide to colour its nodes with k distinct colours, labelled from 1 to k. Then for each colour i = 1, 2, · · · , k, define Ei as the minimum subset of edges connecting all nodes coloured by i. If there is no node of the tree coloured by a specified colour i, Ei will be empty.
Try to decide a colour scheme to maximize the size of E1 ∩ E2 · · · ∩ Ek, and output its size.  


Input The first line of input contains an integer T (1 ≤ T ≤ 1000), indicating the total number of test cases.
For each case, the first line contains two positive integers n which is the size of the tree and k (k ≤ 500) which is the number of colours. Each of the following n - 1 lines contains two integers x and y describing an edge between them. We are sure that the given graph is a tree.
The summation of n in input is smaller than or equal to 200000.  


Output For each test case, output the maximum size of E1 ∩ E1 ... ∩ Ek.  


Sample Input 3 4 2 1 2 2 3 3 4 4 2 1 2 1 3 1 4 6 3 1 2 2 3 3 4 3 5 6 2  


Sample Output 1 0 1   題意: 考慮一個非根樹,它不是樹或植物的生物學意義,而是一個樹作為圖論中的無向圖,有n個節點,從1到n標記。 如果你在這裡無法理解樹的概念,請省略這個問題。
現在我們決定用k個不同的顏色為節點著色,標記為1到k。 然後,對於每種顏色i = 1,2,...,k,將Ei定義為連線由i著色的所有節點的邊的最小子集。 如果樹的節點沒有由指定顏色i著色,則Ei將為空。
嘗試確定一個配色方案,以最大化E1∩E2···∩Ek的大小,並輸出其大小。
    很明顯的一點是:我們K種顏色都要使用,否則一個集合為0,則其交集必然為0; 不僅如此,當我們割去一條邊時,樹分為兩個部分,若兩部分大小均>=K,那麼ans++; 因為我們列舉的是邊,那麼如果是交集裡的邊,則兩邊的numV>=k,那麼我們dfs一次求其子樹大小即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/
int n;
vector<int>vc[maxn];
int Siz[maxn];

void dfs(int u, int rt) {
	Siz[u] = 1;
	for (int i = 0; i < vc[u].size(); i++) {
		int v = vc[u][i];
		if (v == rt)continue;
		dfs(v, u); Siz[u] += Siz[v];
	}
}

int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	int T; rdint(T);
	while (T--) {
		int k; rdint(n); rdint(k);
		for (int i = 0; i < maxn; i++)vc[i].clear();
		for (int i = 1; i < n; i++) {
			int u, v; rdint(u); rdint(v);
			vc[u].push_back(v); vc[v].push_back(u);
		}
		dfs(1, 0);
		int ans = 0;
		for (int i = 1; i <= n; i++) {
			if (Siz[i] >= k && (n - Siz[i]) >= k)ans++;
		}
		cout << ans << endl;
	}
    return 0;
}