codeforces #345(div2)

来源:互联网 发布:深圳网络教育机构 编辑:程序博客网 时间:2024/04/23 15:54

链接:戳这里

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

Friends are going to play console. They have two joysticks and only one charger for them. Initially first joystick is charged at a1 percent and second one is charged at a2 percent. You can connect charger to a joystick only at the beginning of each minute. In one minute joystick either discharges by 2 percent (if not connected to a charger) or charges by 1 percent (if connected to a charger).

Game continues while both joysticks have a positive charge. Hence, if at the beginning of minute some joystick is charged by 1 percent, it has to be connected to a charger, otherwise the game stops. If some joystick completely discharges (its charge turns to 0), the game also stops.

Determine the maximum number of minutes that game can last. It is prohibited to pause the game, i. e. at each moment both joysticks should be enabled. It is allowed for joystick to be charged by more than 100 percent.

Input

The first line of the input contains two positive integers a1 and a2 (1 ≤ a1, a2 ≤ 100), the initial charge level of first and second joystick respectively.

Output

Output the only integer, the maximum number of minutes that the game can last. Game continues until some joystick is discharged.

Examples
input
3 5
output
6
input
4 4
output
5
Note

In the first sample game lasts for 6 minute by using the following algorithm:

  • at the beginning of the first minute connect first joystick to the charger, by the end of this minute first joystick is at 4%, second is at 3%;
  • continue the game without changing charger, by the end of the second minute the first joystick is at 5%, second is at 1%;
  • at the beginning of the third minute connect second joystick to the charger, after this minute the first joystick is at 3%, the second one is at 2%;
  • continue the game without changing charger, by the end of the fourth minute first joystick is at 1%, second one is at 3%;
  • at the beginning of the fifth minute connect first joystick to the charger, after this minute the first joystick is at 2%, the second one is at 1%;
  • at the beginning of the sixth minute connect second joystick to the charger, after this minute the first joystick is at 0%, the second one is at 2%.

After that the first joystick is completely discharged and the game is stopped.


题意:两个人用手柄玩游戏,但是只有一个充电器,所以必须轮流充电。玩游戏的时候插充电器的手柄每一秒充百分之一的电,不插的手柄每一秒耗费百分之二的电,手柄充电量最多到百分之百,给定A B手柄的初始电量,问两个人在最优充电的情况下能玩多少秒。

思路:模拟游戏的过程,电量多的手柄不插充电器,电量少的插。

代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1using namespace std;int a1,a2;int main(){    scanf("%d%d",&a1,&a2);    int num=0;    while(a1 && a2){        if(a1>=a2){            if(a1==1) break;            a1-=2;            a2++;        }else{            if(a2==1) break;            a2-=2;            a1++;        }        num++;    }    printf("%d\n",num);    return 0;}

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

There are n pictures delivered for the new exhibition. The i-th painting has beauty ai. We know that a visitor becomes happy every time he passes from a painting to a more beautiful one.

We are allowed to arranged pictures in any order. What is the maximum possible number of times the visitor may become happy while passing all pictures from first to last? In other words, we are allowed to rearrange elements of a in any order. What is the maximum possible number of indices i (1 ≤ i ≤ n - 1), such that ai + 1 > ai.

Input

The first line of the input contains integer n (1 ≤ n ≤ 1000) — the number of painting.

The second line contains the sequence a1, a2, ..., an (1 ≤ ai ≤ 1000), where ai means the beauty of the i-th painting.

Output

Print one integer — the maximum possible number of neighbouring pairs, such that ai + 1 > ai, after the optimal rearrangement.

Examples
input
520 30 10 50 40
output
4
input
4200 100 100 200
output
2
Note

In the first sample, the optimal order is: 10, 20, 30, 40, 50.

In the second sample, the optimal order is: 100, 200, 100, 200.


题意:游客观看画展,一共有n(1<=n<=1000)幅画,每一幅画都有一个美丽程度ai(1<=ai<=1000),游客从第一幅画看到最后一幅,如果当前看到的第i幅画的美丽程度严格大于第i-1幅画,这个游客的喜悦程度会增加1,问如何摆放画的位置使游客的喜悦度最大。

思路:计算出美丽程度为1~1000的画的数目,从1到1000暴力找数目不为0的值,有就+1,数目相对减一。这里需要注意一个地方,只剩下一幅画的时候不需要+1

代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1using namespace std;int n;int a[10010],num[100100];int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++) {        scanf("%d",&a[i]);        num[a[i]]++;    }    int ans=0;    while(1){        int flag=0,t=0;        for(int i=1;i<=1000;i++){            if(num[i]){                if(flag==0) flag=1;                else {                    flag=1;                    ans++;                }                num[i]--;            }            else t++;        }        ///for(int i=1;i<=1000;i++){        ///    if(num[i]) cout<<i<<" ";        ///}        ///cout<<ans<<endl;        if(t==1000) {            cout<<ans<<endl;            return 0;        }    }    return 0;}

C. Watchmen
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Watchmen are in a danger and Doctor Manhattan together with his friend Daniel Dreiberg should warn them as soon as possible. There are n watchmen on a plane, the i-th watchman is located at point (xi, yi).

They need to arrange a plan, but there are some difficulties on their way. As you know, Doctor Manhattan considers the distance between watchmen i and j to be |xi - xj| + |yi - yj|. Daniel, as an ordinary person, calculates the distance using the formula .

The success of the operation relies on the number of pairs (i, j) (1 ≤ i < j ≤ n), such that the distance between watchman i and watchmen j calculated by Doctor Manhattan is equal to the distance between them calculated by Daniel. You were asked to compute the number of such pairs.

Input

The first line of the input contains the single integer n (1 ≤ n ≤ 200 000) — the number of watchmen.

Each of the following n lines contains two integers xi and yi (|xi|, |yi| ≤ 109).

Some positions may coincide.

Output

Print the number of pairs of watchmen such that the distance between them calculated by Doctor Manhattan is equal to the distance calculated by Daniel.

Examples
input
31 17 51 5
output
2
input
60 00 10 2-1 10 11 1
output
11
Note

In the first sample, the distance between watchman 1 and watchman 2 is equal to |1 - 7| + |1 - 5| = 10 for Doctor Manhattan and  for Daniel. For pairs (1, 1)(1, 5) and (7, 5)(1, 5) Doctor Manhattan and Daniel will calculate the same distances.


题意:二维平面内给定n(1<=n<=200000)个点,每个点的x,y坐标均为整数(0<=|xi|,|yi|<=1e9),问有多少点对满足Manhattan距离==Daniel距离,存在重点。

思路:显然满足条件的两个点必须x1==x2 || y1==y2。统计一下每个x或y上有多少点(map),ans+=C(num,2)。但是因为存在重点,所以还需要减去重复计算的点对。

代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1using namespace std;int n;int x[200100],y[200100];map<int,int> mp1;map<int,int> mp2;struct node{    int x,y;}s[200100];bool cmp(node a,node b){    if(a.x==b.x) return a.y<b.y;    return a.x<b.x;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++) {        scanf("%d%d",&x[i],&y[i]);        mp1[x[i]]++;        mp2[y[i]]++;        s[i].x=x[i];        s[i].y=y[i];    }    sort(s+1,s+n+1,cmp);    ll ans1=0,ans2=0;    int t;    for(int i=1;i<n;i++){        t=1;        while(s[i].x==s[i+1].x && s[i].y==s[i+1].y && i<n){            t++;            i++;        }        ans1+=(ll)t*(t-1)/2;    }    int num=0;    for(int i=1;i<=n;i++){        num=mp1[x[i]];        mp1[x[i]]=0;        ans2+=(ll)num*(num-1)/2;        num=mp2[y[i]];        mp2[y[i]]=0;        ans2+=(ll)num*(num-1)/2;    }    printf("%I64d\n",ans2-ans1);    return 0;}

D. Image Preview
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Vasya's telephone contains n photos. Photo number 1 is currently opened on the phone. It is allowed to move left and right to the adjacent photo by swiping finger over the screen. If you swipe left from the first photo, you reach photo n. Similarly, by swiping right from the last photo you reach photo 1. It takes a seconds to swipe from photo to adjacent.

For each photo it is known which orientation is intended for it — horizontal or vertical. Phone is in the vertical orientation and can't be rotated. It takes b second to change orientation of the photo.

Vasya has T seconds to watch photos. He want to watch as many photos as possible. If Vasya opens the photo for the first time, he spends 1 second to notice all details in it. If photo is in the wrong orientation, he spends b seconds on rotating it before watching it. If Vasya has already opened the photo, he just skips it (so he doesn't spend any time for watching it or for changing its orientation). It is not allowed to skip unseen photos.

Help Vasya find the maximum number of photos he is able to watch during T seconds.

Input

The first line of the input contains 4 integers n, a, b, T (1 ≤ n ≤ 5·1051 ≤ a, b ≤ 10001 ≤ T ≤ 109) — the number of photos, time to move from a photo to adjacent, time to change orientation of a photo and time Vasya can spend for watching photo.

Second line of the input contains a string of length n containing symbols 'w' and 'h'.

If the i-th position of a string contains 'w', then the photo i should be seen in the horizontal orientation.

If the i-th position of a string contains 'h', then the photo i should be seen in vertical orientation.

Output

Output the only integer, the maximum number of photos Vasya is able to watch during those T seconds.

Examples
input
4 2 3 10wwhw
output
2
input
5 2 4 13hhwhh
output
4
input
5 2 4 1000hhwhh
output
5
input
3 1 100 10whw
output
0
Note

In the first sample test you can rotate the first photo (3 seconds), watch the first photo (1 seconds), move left (2 second), rotate fourth photo (3 seconds), watch fourth photo (1 second). The whole process takes exactly 10 seconds.

Note that in the last sample test the time is not enough even to watch the first photo, also you can't skip it.

题意:给定n张照片,每看一张没看过的照片需要1秒,每左右滑动一次 需要a秒,但是状态为'w'的照片需要翻转,每翻转一次需要b秒,状态为'h'的照片可以直接看。问在给定的t秒内最多看多少张照片。必须从第一张照片开始看,没看过的照片不能跳跃。


思路:左右平铺开照片即为(2,3,4...n,1,2,3,..n-1,n)。
暴力枚举右边看多少张,二分左边最多可以看多少张。
暴力枚举左边看多少张,二分右边最多可以看多少张。
大模拟题...

代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1using namespace std;int n,m,A,B,T,TT,ans;char a[1000100],b[1000100];int v[1000100];void init(){    int t=0;    for(int i=n-1;i>=1;i--){        if(b[i]=='w') t+=B;        t+=A+1;        v[i]=t;    }    t=0;    for(int i=n+1;i<=m;i++){        if(b[i]=='w') t+=B;        t+=A+1;        v[i]=t;    }}bool solve(int x){    if(v[x]>T) return false;    return true;}bool solve1(int x){    if(v[x]>T) return false;    return true;}int main(){    ans=0;    scanf("%d%d%d%d",&n,&A,&B,&TT);    scanf("%s",a+1);    m=2*n-1;    for(int i=1;i<=n;i++) b[i+n-1]=a[i];    for(int i=1;i<=n-1;i++) b[i]=a[i+1];    int t=0;    init();    for(int i=n;i<=m;i++){        T=TT;        if(b[i]=='w') t=t+B;        if(i!=n) t=t+A+1;        else t++;        int num=i-n+1;        if(t>T) break;        ans=max(ans,num);        T=T-t;T=T-(num-1)*A;        if(T<0) continue;        int l=1,r=n-1,mid,flag=n;        while(l<r){            int mid=(l+r)/2;            if(solve(mid)) {                r=mid;                flag=mid;            }            else l=mid+1;        }        ans=max(ans,n-flag+num);    }    t=0;    for(int i=n;i>=1;i--){        T=TT;        if(b[i]=='w') t+=B;        if(i!=n) t+=A+1;        else t++;        int num=n-i+1;        if(t>T) break;        ans=max(ans,num);        T-=t;T-=(num-1)*A;        if(T<0) continue;        int l=n+1,r=m,mid,flag=n;        while(l<r) {            mid=(l+r)/2;            if(solve1(mid)) {                l=mid+1;                flag=mid;            }            else r=mid;        }        ans=max(ans,flag-n+num);    }    ans=min(ans,n);    cout<<ans<<endl;    return 0;}

E. Table Compression
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Little Petya is now fond of data compression algorithms. He has already studied gzbzzip algorithms and many others. Inspired by the new knowledge, Petya is now developing the new compression algorithm which he wants to name dis.

Petya decided to compress tables. He is given a table a consisting of n rows and m columns that is filled with positive integers. He wants to build the table a' consisting of positive integers such that the relative order of the elements in each row and each column remains the same. That is, if in some row i of the initial table ai, j < ai, k, then in the resulting table a'i, j < a'i, k, and if ai, j = ai, k then a'i, j = a'i, k. Similarly, if in some column j of the initial table ai, j < ap, j then in compressed table a'i, j < a'p, j and if ai, j = ap, j then a'i, j = a'p, j.

Because large values require more space to store them, the maximum value in a' should be as small as possible.

Petya is good in theory, however, he needs your help to implement the algorithm.

Input

The first line of the input contains two integers n and m (, the number of rows and the number of columns of the table respectively.

Each of the following n rows contain m integers ai, j (1 ≤ ai, j ≤ 109) that are the values in the table.

Output

Output the compressed table in form of n lines each containing m integers.

If there exist several answers such that the maximum number in the compressed table is minimum possible, you are allowed to output any of them.

Examples
input
2 21 23 4
output
1 22 3
input
4 320 10 3050 40 3050 60 7090 80 70
output
2 1 35 4 35 6 79 8 7
Note

In the first sample test, despite the fact a1, 2 ≠ a21, they are not located in the same row or column so they may become equal after the compression.

题意:给定一个n*m的矩阵,你需要精简成另外一个n*m的矩阵。

这两个矩阵必须要求每一行每一列的大小顺序不变。


题解:显然我们可以先从小到大排序,然后插进矩阵。

但是出现相同的数怎么处理。你必须要矩阵上把所有相同的数都赋值成当前第k小。

找出每一行或每一列的相同的数所在的位置,然后跑并查集将这些相同的位置拧成一团。

然后寻找所有相同位置上的坐标x,y所在的行列的最大值。

找出最大值然后加1就是所有相同的数所在的位置的值。

代码的具体实现是仿照卿神的  链接:戳这里


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1using namespace std;int n,m;int fa[1000100],X[1000100],Y[1000100],anw[1000100],Vx[1000100],Vy[1000100];pair<int,pair<int,int> > A[1000100];int find(int x){    if(x!=fa[x]){        fa[x]=find(fa[x]);    }    return fa[x];}void Union(int u,int v){    int xx=find(u);    int yy=find(v);    if(xx!=yy) fa[xx]=yy;}int main(){    scanf("%d%d",&n,&m);    for(int i=0;i<n*m;i++){        fa[i]=i;        scanf("%d",&A[i].first);        A[i].second.first=i/m;        A[i].second.second=i%m;    }    sort(A,A+n*m);    int l=-1;    for(int j=0;j<n*m;j++){        if(j!=n*m-1 && A[j].first==A[j+1].first) continue;        for(int i=l+1;i<=j;i++){            int pos=A[i].second.first*m+A[i].second.second;            int x=A[i].second.first*m,y=A[i].second.second;            X[x]=pos;            Y[y]=pos;        }        for(int i=l+1;i<=j;i++){            int pos=A[i].second.first*m+A[i].second.second;            int x=A[i].second.first*m,y=A[i].second.second;            Union(X[x],pos);            Union(Y[y],pos);        }        for(int i=l+1;i<=j;i++){            int pos=A[i].second.first*m+A[i].second.second;            int x=A[i].second.first*m,y=A[i].second.second;            int p=find(pos);            anw[p]=max(anw[p],max(Vx[x],Vy[y])+1);        }        for(int i=l+1;i<=j;i++){            int pos=A[i].second.first*m+A[i].second.second;            int x=A[i].second.first*m,y=A[i].second.second;            int p=find(pos);            Vx[x]=max(Vx[x],anw[p]);            Vy[y]=max(Vy[y],anw[p]);        }        l=j;    }    for(int i=0;i<n*m;i++){        int p=find(i);        printf("%d ",anw[p]);        if(i%m==(m-1)) printf("\n");    }    return 0;}




暴力枚举右边看多少张,二分左边最多可以看多少张。
0 0
原创粉丝点击