2017 ACM-ICPC 亚洲区(北京赛区)网络赛

 

题目1 : Visiting Peking University

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

Ming is going to travel for n days and the date of these days can be represented by n integers: 0, 1, 2, …, n-1. He plans to spend m consecutive days(2 ≤ m ≤ n)in Beijing. During these m days, he intends to use the first day and another day to visit Peking university. Before he made his plan, Ming investigated on the number of tourists who would be waiting in line to enter Peking university during his n-day trip, and the results could be represented by an integer sequence p[i] (0 ≤ i ≤ n-1, p[i] represents the number of waiting tourists on day i). To save time, he hopes to choose two certain dates a and b to visit PKU(0 ≤ a < b ≤ n-1), which makes p[a] + p[b] as small as possible.

Unfortunately, Ming comes to know that traffic control will be taking place in Beijing on some days during his n-day trip, and he won’t be able to visit any place in Beijing, including PKU, on a traffic control day. Ming loves Beijing and he wants to make sure that m days can be used to visit interesting places in Beijing. So Ming made a decision:  spending k (m ≤ k ≤ n) consecutive days in Beijing is also acceptable if there are k - m traffic control days among those k days. Under this complicated situation, he doesn’t know how to make the best schedule. Please write a program to help Ming determine the best dates of the two days to visit Peking University.  Data guarantees a unique solution.

输入

There are no more than 20 test cases.

For each test case:

The first line contains two integers, above mentioned n and m (2 ≤ n ≤ 100, 2 ≤ m ≤ n).

The second line contains n integers, above mentioned p[0] , p[1] , … p[n-1]. (0 ≤ p[i] ≤ 1000, i = 0 ... n-1)

The third line is an integer q (0 ≤ q ≤ n), representing the total number of traffic control days during the n-day trip, followed by q integers representing the dates of these days.

输出

One line, including two integers a and b, representing the best dates for visiting PKU.

样例输入

7 3
6 9 10 1 0 8 35
3 5 6 2
4 2
10 11 1 2
1 2

样例输出

0 3
1 3

说下题意:Ming要去参观PKU,一共有n天,每天参观pku的人为p[i]个。不幸的是beijing要交通管制m天,所以Ming想在beijing连续k天,使得k天内恰好有k-m天交通管制,然后求出Ming参观PKU要花费的最少时间,并且Ming必须从第一天开始。

 

 

代码如下:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;

int n,m,a[110],q,vis[110];

int main(){
	while(~scanf("%d%d",&n,&m)){
		memset(vis,0,sizeof(vis));
		for(int i = 0; i < n; i ++) scanf("%d",&a[i]);
		scanf("%d",&q);
		int num,mxx = inf, sum = inf, indx,x,y;
		for(int i = 0; i < q; i ++) scanf("%d",&num), vis[num] = 1;
		for(int i = 0; i < n; i ++){
			for(int j = 0; j <= i; j ++){
				int cnt = 0;
				if(i - j + 1 - m >= 0){ 
					for(int k = j; k <= i; k ++) if(vis[k]) cnt ++;
					if(cnt == i-j+1-m && !vis[j]){ 
						mxx = inf;
						for(int k = j+1; k <= i; k ++){
							if(a[k] < mxx && !vis[k]){
								mxx = a[k];  indx = k;
							}
						}
						if(mxx + a[j] < sum) sum = mxx + a[j],x=indx,y = j;
					}
				}	
			}
		}
		printf("%d %d\n",y,x);
	}
	return 0;
}

 

 

 

 

题目7 : Bounce

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

For Argo, it is very interesting watching a circle bouncing in a rectangle.

As shown in the figure below, the rectangle is divided into N×M grids, and the circle fits exactly one grid.

The bouncing rule is simple:

1. The circle always starts from the left upper corner and moves towards lower right.

2. If the circle touches any edge of the rectangle, it will bounce.

3. If the circle reaches any corner of the rectangle after starting, it will stop there.

Argo wants to know how many grids the circle will go through only once until it first reaches another corner. Can you help him?

输入

The input consists of multiple test cases. (Up to 105)

For each test case:

One line contains two integers N and M, indicating the number of rows and columns of the rectangle. (2 ≤ N, M ≤ 109)

输出

For each test case, output one line containing one integer, the number of grids that the circle will go through exactly once until it stops (the starting grid and the ending grid also count).

样例输入

2 2
2 3
3 4
3 5
4 5
4 6
4 7
5 6
5 7
9 15

样例输出

2
3
5
5
7
8
7
9
11
39

博客链接:http://blog.csdn.net/joovo/article/details/78089476http://www.cnblogs.com/Jadon97/p/7583835.html

 

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;

int gcd(int n, int m){
	return m == 0 ? n : gcd(m,n%m);
}

int main(){
	LL n,m;
	while(~scanf("%lld%lld",&n,&m)){
		m --; n --;
		LL r = gcd(n,m);
		LL lcm = (m / r) * n + 1;
		n = n / r - 1; m = m / r - 1;
		printf("%lld\n",lcm - n*m );
	}
	return 0;
}

 

 

 

 

 

 

题目9 : Minimum

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

You are given a list of integers a0, a1, …, a2^k-1.

You need to support two types of queries:

1. Output Minx,y∈[l,r] {ax∙ay}.

2. Let ax=y.

输入

The first line is an integer T, indicating the number of test cases. (1≤T≤10).

For each test case:

The first line contains an integer k (0 ≤ k ≤ 17).

The following line contains 2k integers, a0, a1, …, a2^k-1 (-2k ≤ ai < 2k).

The next line contains a integer  (1 ≤ Q < 2k), indicating the number of queries. Then next Q lines, each line is one of:

1. 1 l r: Output Minx,y∈[l,r]{ax∙ay}. (0 ≤ l ≤ r < 2k)

2. 2 x y: Let ax=y. (0 ≤ x < 2k, -2k ≤ y < 2k)

输出

For each query 1, output a line contains an integer, indicating the answer.

样例输入

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

样例输出

1
1
4

 

 

 

 

题目让求的是给定一个区间,求该区间ax和ay相乘的结果最小的(ax和ay可以是同一个数),则分两种情况①:当最小的数大于0等于时,则最小数自乘即可②当最小数小于0时,判断最大数的正负,如果最大数大于0,则把最大最小数相乘即可,如果最大数小于0,则最大数自乘即可,所以题目就转换成了求一个连续区间的最大最小数,线段树求解即可。

 

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define ls rt << 1
#define rs rt << 1 | 1
#define inf 0x3f3f3f3f
using namespace std;

const int maxn = 150000;
int k,t;
LL sum1[maxn<<2],sum[maxn<<2],a[maxn],n,q;

void pushup(int rt){
	sum[rt] = min(sum[ls],sum[rs]);
	sum1[rt] = max(sum1[ls],sum1[rs]);
}

void build(int l, int r, int rt){
	if(l == r){
		sum1[rt] = a[l];
		sum[rt] = a[l];
		return ;
	}
	int m = (l + r) >> 1;
	build(l,m,ls);
	build(m+1,r,rs);
	pushup(rt);
}

void update(int l, int r, int rt, int cur, int c){
	if(l == r){
		sum[rt] = c; sum1[rt] = c; return ;
	}
	int m = (l + r) >> 1;
	if(cur <= m) update(l,m,ls,cur,c);
	else update(m+1,r,rs,cur,c);
	pushup(rt);
}

LL query_Min(int L, int R, int l, int r, int rt){
	if(L <= l && r <= R) return sum[rt];
	int m = (l + r) >> 1;
	LL ans = inf;
	if(L <= m) ans = min(query_Min(L,R,l,m,ls),ans);
	if(R > m) ans = min(query_Min(L,R,m+1,r,rs),ans);
	return ans;
}

LL query_Max(int L, int R, int l, int r, int rt){
	if(L <= l && r <= R) return sum1[rt];
	int m = (l + r) >> 1;
	LL ans = -inf;
	if(L <= m) ans = max(query_Max(L,R,l,m,ls),ans);
	if(R > m) ans = max(query_Max(L,R,m+1,r,rs),ans);
	return ans;
}

int main(){
	scanf("%d",&t);
	while(t --){
		scanf("%d",&k);
		n = 1;
		memset(sum,0,sizeof(sum));
		memset(sum1,0,sizeof(sum1));
		for(int i = 0; i < k; i ++) n *= 2;
		for(int i = 1; i <= n; i ++) scanf("%lld",&a[i]);
		build(1,n,1);
		scanf("%lld",&q);
		int f,x,y;
		while(q --){
			scanf("%d%d%d",&f,&x,&y);
			if(f == 1){
				LL Min = query_Min(x+1,y+1,1,n,1);
				if(Min >= 0) printf("%lld\n",Min*Min);
				else{
					LL Max = query_Max(x+1,y+1,1,n,1);
					if(Max <= 0) printf("%lld\n",Max*Max);
					else printf("%lld\n",Max*Min);
				}
			}
			else{
				update(1,n,1,x+1,y);
			}
		}
	}
	return 0;
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值