Codeforces Round #274 (Div. 2)

A. Expression
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Petya studies in a school and he adores Maths. His class has been studying arithmetic expressions. On the last class the teacher wrote three positive integers abc on the blackboard. The task was to insert signs of operations '+' and '*', and probably brackets between the numbers so that the value of the resulting expression is as large as possible. Let's consider an example: assume that the teacher wrote numbers 1, 2 and 3 on the blackboard. Here are some ways of placing signs and brackets:

  • 1+2*3=7
  • 1*(2+3)=5
  • 1*2*3=6
  • (1+2)*3=9

Note that you can insert operation signs only between a and b, and between b and c, that is, you cannot swap integers. For instance, in the given sample you cannot get expression (1+3)*2.

It's easy to see that the maximum value that you can obtain is 9.

Your task is: given ab and c print the maximum value that you can get.

Input

The input contains three integers ab and c, each on a single line (1 ≤ a, b, c ≤ 10).

Output

Print the maximum value of the expression that you can obtain.

Sample test(s)
input
1
2
3
output
9
题意
给出3个数,你可以加给他们加括号、加号、乘号做运算,求结果最大是多少
思路
暴力,dfs,dp都行,随便搞
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<string>
using namespace std;
//cin.sync_with_stdio(false);
#define mod 1000000007
#define LL long long
#define ULL unsigned long long

int ans=0;
int a[3];
int dp[3][3];
int dfs(int l,int r){
    if(dp[l][r]!=-1) return dp[l][r];
    if(l==r)
        dp[l][r]=a[l];
    for(int i=l;i<r;i++){
        dp[l][r] = max(dp[l][r],dfs(l,i)+dfs(i+1,r));
        dp[l][r] = max(dp[l][r],dfs(l,i)*dfs(i+1,r));
    }
    return dp[l][r];
        
}
int main(void){
    for(int i=0;i<3;i++) cin>>a[i];
    memset(dp,-1,sizeof(dp));
    printf("%d\n",dfs(0,2));
    
    return 0;
}

B. Towers
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

As you know, all the kids in Berland love playing with cubes. Little Petya has n towers consisting of cubes of the same size. Tower with number i consists of ai cubes stacked one on top of the other. Petya defines the instability of a set of towers as a value equal to the difference between the heights of the highest and the lowest of the towers. For example, if Petya built five cube towers with heights (8, 3, 2, 6, 3), the instability of this set is equal to 6 (the highest tower has height 8, the lowest one has height 2).

The boy wants the instability of his set of towers to be as low as possible. All he can do is to perform the following operation several times: take the top cube from some tower and put it on top of some other tower of his set. Please note that Petya would never put the cube on the same tower from which it was removed because he thinks it's a waste of time.

Before going to school, the boy will have time to perform no more than k such operations. Petya does not want to be late for class, so you have to help him accomplish this task.

Input

The first line contains two space-separated positive integers n and k (1 ≤ n ≤ 1001 ≤ k ≤ 1000) — the number of towers in the given set and the maximum number of operations Petya can perform. The second line contains n space-separated positive integers ai(1 ≤ ai ≤ 104) — the towers' initial heights.

Output

In the first line print two space-separated non-negative integers s and m (m ≤ k). The first number is the value of the minimum possible instability that can be obtained after performing at most k operations, the second number is the number of operations needed for that.

In the next m lines print the description of each operation as two positive integers i and j, each of them lies within limits from 1 to n. They represent that Petya took the top cube from the i-th tower and put in on the j-th one (i ≠ j). Note that in the process of performing operations the heights of some towers can become equal to zero.

If there are multiple correct sequences at which the minimum possible instability is achieved, you are allowed to print any of them.

Sample test(s)
input
3 2
5 8 5
output
0 2
2 1
2 3
题意
给n座塔的高度,每座塔由相同尺寸的方块组成,你有k次操作,每次可以使一座塔高度-1,另一座塔+1,求最终最高与最矮塔的高度差最小的操作,操作方案小于等于k
思路
每次把最高的给最低执行k次,当最高与最低的差为1时退出
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<string>
using namespace std;
//cin.sync_with_stdio(false);
#define mod 1000000007
#define LL long long
#define ULL unsigned long long

int n,m;
int a[105];
vector<pair<int,int> > v;
int main(void){
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>a[i];
    int ma,mi,cou=0;;
    while(cou<m){
        ma=mi=0;
        for(int i=1;i<n;i++){
            if(a[i]>a[ma]) ma=i;
            if(a[i]<a[mi]) mi=i;
        }
        if(a[ma]-a[mi]<=1) break;
        v.push_back(make_pair(ma+1,mi+1));
        a[ma]--;
        a[mi]++;
        cou++;
    }
    mi=ma=0;
    for(int i=1;i<n;i++){
        if(a[i]>a[ma]) ma=i;
        if(a[i]<a[mi]) mi=i;
    }
    printf("%d %d\n",a[ma]-a[mi],v.size());
    for(int i=0;i<v.size();i++)
        printf("%d %d\n",v[i].first,v[i].second);
    return 0;
}

C. Exams
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Student Valera is an undergraduate student at the University. His end of term exams are approaching and he is to pass exactly n exams. Valera is a smart guy, so he will be able to pass any exam he takes on his first try. Besides, he can take several exams on one day, and in any order.

According to the schedule, a student can take the exam for the i-th subject on the day number ai. However, Valera has made an arrangement with each teacher and the teacher of the i-th subject allowed him to take an exam before the schedule time on day bi(bi < ai). Thus, Valera can take an exam for the i-th subject either on day ai, or on day bi. All the teachers put the record of the exam in the student's record book on the day of the actual exam and write down the date of the mark as number ai.

Valera believes that it would be rather strange if the entries in the record book did not go in the order of non-decreasing date. Therefore Valera asks you to help him. Find the minimum possible value of the day when Valera can take the final exam if he takes exams so that all the records in his record book go in the order of non-decreasing date.

Input

The first line contains a single positive integer n (1 ≤ n ≤ 5000) — the number of exams Valera will take.

Each of the next n lines contains two positive space-separated integers ai and bi (1 ≤ bi < ai ≤ 109) — the date of the exam in the schedule and the early date of passing the i-th exam, correspondingly.

Output

Print a single integer — the minimum possible number of the day when Valera can take the last exam if he takes all the exams so that all the records in his record book go in the order of non-decreasing date.

Sample test(s)
input
3
5 2
3 1
4 2
output
2
题意
有n场考试,每场的考试时间为ai,你可以另它提前到bi考或到ai才考。你可以自己安排每场比赛在什么时候考,但每考一场就会把它的ai记录下来,最终的序列必须是非递减的,求最后一天最早可以在什么时候考
思路
因为最终是按ai从小到大,如果一场考试提前了则后面不能有小于它的ai,很容易想到就是先按ai从小到大排,再按bi从小到大排。当ai相同的情况下,你可以根据上一场考试的时间,判断是否要另当场为bi还是ai,如果bi大于等于上一场的时间,否则ai
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<string>
using namespace std;
//cin.sync_with_stdio(false);
#define mod 1000000007
#define LL long long
#define ULL unsigned long long

vector<pair<int,int> > v;
int n,a,b;
int main(void){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&a,&b);
        v.push_back(make_pair(a,b));
    }
    sort(v.begin(),v.end());
    int w=0;
    for(int i=0;i<n;i++){
        if(v[i].second>=w)
            w=v[i].second;
        else w=v[i].first;
    }
    printf("%d\n",w);
    return 0;
}

D. Long Jumps
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Valery is a PE teacher at a school in Berland. Soon the students are going to take a test in long jumps, and Valery has lost his favorite ruler!

However, there is no reason for disappointment, as Valery has found another ruler, its length is l centimeters. The ruler already has nmarks, with which he can make measurements. We assume that the marks are numbered from 1 to n in the order they appear from the beginning of the ruler to its end. The first point coincides with the beginning of the ruler and represents the origin. The last mark coincides with the end of the ruler, at distance l from the origin. This ruler can be repesented by an increasing sequence a1, a2, ..., an, where ai denotes the distance of the i-th mark from the origin (a1 = 0an = l).

Valery believes that with a ruler he can measure the distance of d centimeters, if there is a pair of integers i and j (1 ≤ i ≤ j ≤ n), such that the distance between the i-th and the j-th mark is exactly equal to d (in other words, aj - ai = d).

Under the rules, the girls should be able to jump at least x centimeters, and the boys should be able to jump at least y (x < y) centimeters. To test the children's abilities, Valery needs a ruler to measure each of the distances x and y.

Your task is to determine what is the minimum number of additional marks you need to add on the ruler so that they can be used to measure the distances x and y. Valery can add the marks at any integer non-negative distance from the origin not exceeding the length of the ruler.

Input

The first line contains four positive space-separated integers nlxy (2 ≤ n ≤ 1052 ≤ l ≤ 1091 ≤ x < y ≤ l) — the number of marks, the length of the ruler and the jump norms for girls and boys, correspondingly.

The second line contains a sequence of n integers a1, a2, ..., an (0 = a1 < a2 < ... < an = l), where ai shows the distance from the i-th mark to the origin.

Output

In the first line print a single non-negative integer v — the minimum number of marks that you need to add on the ruler.

In the second line print v space-separated integers p1, p2, ..., pv (0 ≤ pi ≤ l). Number pi means that the i-th mark should be at the distance of pi centimeters from the origin. Print the marks in any order. If there are multiple solutions, print any of them.

Sample test(s)
input
3 250 185 230
0 185 250
output
1
230
题意
有一把n个刻度的尺,尺的长度为l,第一个刻度为0,第n个刻度为l
你必须能够算出两个刻度,x与y,x<y
如果尺子上拥有该点,或其中两个刻度相减可以得到这个尺寸,即是可以算出这个刻度
问至少需要添加几个点能算出x与y,添加的点必须大于0且小于l
思路
答案肯定只有3个,【0,1,2】
0:两个刻度都可以算出
1:①只有x不存在,添加x ②只有y不存在,添加y ③x与y都不存在,通过添加某一个点可以同时算出x与y
2:x与y都不存在,且必须添加两个点,添加x与y即可
 
   
判断一个数a是否存在,只需要二分找该数,如果找不到,通过枚举比它大的数b,再二分b-a是否存在,如果存在即是能算出该数
接着麻烦的是处理只添加一个点且x与y都不存在的情况,通过多开一个集合,集合里的点为新添能得到x的,最后在这个集合与原集合各取一个数判断是否能得到y
 
   
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<string>
using namespace std;
//cin.sync_with_stdio(false);
#define mod 1000000007
#define LL long long
#define ULL unsigned long long

set<int> S,V;
set<int> ::iterator it1,it2;
int n,l,x,y;
vector<int> res;
bool judge(int num){
    it1 = S.lower_bound(num);
    if((*it1)==num) return true;
    else {
        for(;it1!=S.end();it1++){
            int cha = (*it1)-num;
            it2 = S.lower_bound(cha);
            if((*it2)==cha) return true;
        }
        return false;
    }
}
int main(void){
    scanf("%d%d%d%d",&n,&l,&x,&y);
    int a;
    for(int i=0;i<n;i++){
        scanf("%d",&a);
        S.insert(a);
    }
    int ans=0;
    int ok1=judge(x);
    int ok2;
    if(ok1){
        ok2=judge(y);
        if(ok2==0) {
            res.push_back(y);
            ans++;
        }
    }
    else {
        ok2=judge(y);
        if(ok2) {
            res.push_back(x);
            ans++;
        }
        else {
            for(it1=S.end(),it1--;1;it1--){
                int he = (*it1);
                if(he>x) {
                    V.insert(he-x);
                    if(he+x<l)
                        V.insert(he+x);
                }
                else {
                    if(he+x<l)
                        V.insert(he+x);
                }
                if(it1==S.begin()) break;
            }
            int ok=0;
            
            it1 = S.lower_bound(y);
            for(;it1!=S.end();it1++){
                int cha = (*it1)-y;
                it2 = V.lower_bound(cha);
                if((*it2)==cha){
                    res.push_back(*it2);
                    ok=1;
                    break;
                }
            }
            if(!ok){
                it1=V.lower_bound(y);
                if((*it1)==y){
                    ok=1;
                    res.push_back(y);
                }
                if(!ok){
                    for(;it1!=V.end();it1++){
                        int cha = (*it1)-y;
                        it2 = S.lower_bound(cha);
                        if((*it2)==cha){
                            res.push_back(*it1);
                            ok=1;
                            break;
                        }
                    }
                }
                    
            }
            if(!ok) {
                res.push_back(x);
                res.push_back(y);
                ans++;
            }
            
        }
    }
    printf("%d\n",res.size());
    for(int i=0;i<res.size();i++)
        printf("%d ",res[i]);
    return 0;
}

E. Riding in a Lift
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Imagine that you are in a building that has exactly n floors. You can move between the floors in a lift. Let's number the floors from bottom to top with integers from 1 to n. Now you're on the floor number a. You are very bored, so you want to take the lift. Floor number b has a secret lab, the entry is forbidden. However, you already are in the mood and decide to make k consecutive trips in the lift.

Let us suppose that at the moment you are on the floor number x (initially, you were on floor a). For another trip between floors you choose some floor with number y (y ≠ x) and the lift travels to this floor. As you cannot visit floor b with the secret lab, you decided that the distance from the current floor x to the chosen y must be strictly less than the distance from the current floor x to floor b with the secret lab. Formally, it means that the following inequation must fulfill: |x - y| < |x - b|. After the lift successfully transports you to floor y, you write down number y in your notepad.

Your task is to find the number of distinct number sequences that you could have written in the notebook as the result of k trips in the lift. As the sought number of trips can be rather large, find the remainder after dividing the number by 1000000007 (109 + 7).

Input

The first line of the input contains four space-separated integers nabk (2 ≤ n ≤ 50001 ≤ k ≤ 50001 ≤ a, b ≤ na ≠ b).

Output

Print a single integer — the remainder after dividing the sought number of sequences by 1000000007 (109 + 7).

Sample test(s)
input
5 2 4 1
output
2
题意
有n层楼,一开始你在a,你有k次操作,如果当前你在x层,你想跳到y,就必须满足|x-b|>|x-y|,把移动路线记下来,问有多少种序列
思路
一开始想都没想就记忆化加dp暴力写了一发直接就T了,复杂度n*n*k,题目应该最多应该只允许n*k的复杂度
如果想到用前缀和就好做了,其实只要知道每个点能从哪些点转移到该点,这道题的性质是,如果该点是x,能转移到x的最左端点或最右为y,则x到y之间的点都能转移到x除了x。
如果x<b,则最左端肯定为1,右端点为x+(b-x-1)/2,如果x>b,则右端点为n,左端点为x-(x-b-1)/2
所以没执行完一次操作,用一个数组保存1到i所有方案的和,每一次操作只要把sum[r]-sum[l-1]-dp[i],即dp[l]+dp[l+1]……+dp[r]-dp[i],最后输出sum[n]即可
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<string>
using namespace std;
//cin.sync_with_stdio(false);
#define mod 1000000007
#define LL long long
#define ULL unsigned long long

LL dp[5005];
LL sum[5005];
int l[5005],r[5005],n;
inline int abc(int x){
	return x>0?x:-x;
}
void done(){
	memset(sum,0,sizeof(sum));
	for(int i=1;i<=n;i++)
		sum[i]=(sum[i-1]+dp[i])%mod;	
}
int main(void){
	int a,b,k;
	scanf("%d%d%d%d",&n,&a,&b,&k);
	memset(l,3,sizeof(l));
	for(int i=1;i<=n;i++){
		if(i==b) {
			l[i]=r[i]=b;
			continue;
		}
		int cha = abc(i-b);
		cha--;
		if(i<b){
			
			l[i]=1,r[i]=i+cha/2;
		}
		else {
			l[i]=i-cha/2,r[i]=n;
		}
	}

	dp[a]=1;
	done();
	for(int i=1;i<=k;i++){
		for(int j=1;j<=n;j++)
			dp[j]= (sum[r[j]]-sum[l[j]-1]-dp[j]+2*mod)%mod;
		done();
		if(sum[n]==0) break;
	}
	printf("%I64d\n",sum[n]);
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值